Merge branch 'dev' into beta
This commit is contained in:
commit
ffff503e9b
|
@ -197,12 +197,7 @@ namespace MediaBrowser.Api.Movies
|
|||
|
||||
var parentIds = new string[] { };
|
||||
var list = _libraryManager.GetItemList(query, parentIds)
|
||||
.Where(i =>
|
||||
{
|
||||
// Strip out secondary versions
|
||||
var v = i as Video;
|
||||
return v != null && !v.PrimaryVersionId.HasValue;
|
||||
})
|
||||
.DistinctBy(i => i.PresentationUniqueKey, StringComparer.OrdinalIgnoreCase)
|
||||
.DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N"))
|
||||
.ToList();
|
||||
|
||||
|
@ -247,7 +242,7 @@ namespace MediaBrowser.Api.Movies
|
|||
var recentlyPlayedMovies = allMoviesForCategories
|
||||
.Select(i =>
|
||||
{
|
||||
var userdata = _userDataRepository.GetUserData(user.Id, i.GetUserDataKey());
|
||||
var userdata = _userDataRepository.GetUserData(user, i);
|
||||
return new Tuple<BaseItem, bool, DateTime>(i, userdata.Played, userdata.LastPlayedDate ?? DateTime.MinValue);
|
||||
})
|
||||
.Where(i => i.Item2)
|
||||
|
@ -260,7 +255,7 @@ namespace MediaBrowser.Api.Movies
|
|||
.Select(i =>
|
||||
{
|
||||
var score = 0;
|
||||
var userData = _userDataRepository.GetUserData(user.Id, i.GetUserDataKey());
|
||||
var userData = _userDataRepository.GetUserData(user, i);
|
||||
|
||||
if (userData.IsFavorite)
|
||||
{
|
||||
|
|
|
@ -274,7 +274,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
{
|
||||
items = items.Where(i =>
|
||||
{
|
||||
var userdata = UserDataRepository.GetUserData(user.Id, i.GetUserDataKey());
|
||||
var userdata = UserDataRepository.GetUserData(user, i);
|
||||
|
||||
return userdata != null && userdata.Likes.HasValue && !userdata.Likes.Value;
|
||||
});
|
||||
|
@ -284,7 +284,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
{
|
||||
items = items.Where(i =>
|
||||
{
|
||||
var userdata = UserDataRepository.GetUserData(user.Id, i.GetUserDataKey());
|
||||
var userdata = UserDataRepository.GetUserData(user, i);
|
||||
|
||||
return userdata != null && userdata.Likes.HasValue && userdata.Likes.Value;
|
||||
});
|
||||
|
@ -294,7 +294,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
{
|
||||
items = items.Where(i =>
|
||||
{
|
||||
var userdata = UserDataRepository.GetUserData(user.Id, i.GetUserDataKey());
|
||||
var userdata = UserDataRepository.GetUserData(user, i);
|
||||
|
||||
var likes = userdata.Likes ?? false;
|
||||
var favorite = userdata.IsFavorite;
|
||||
|
@ -307,7 +307,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
{
|
||||
items = items.Where(i =>
|
||||
{
|
||||
var userdata = UserDataRepository.GetUserData(user.Id, i.GetUserDataKey());
|
||||
var userdata = UserDataRepository.GetUserData(user, i);
|
||||
|
||||
return userdata != null && userdata.IsFavorite;
|
||||
});
|
||||
|
|
|
@ -519,10 +519,8 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
|
||||
var item = string.IsNullOrEmpty(itemId) ? user.RootFolder : _libraryManager.GetItemById(itemId);
|
||||
|
||||
var key = item.GetUserDataKey();
|
||||
|
||||
// Get the user data for this item
|
||||
var data = _userDataRepository.GetUserData(user.Id, key);
|
||||
var data = _userDataRepository.GetUserData(user, item);
|
||||
|
||||
// Set favorite status
|
||||
data.IsFavorite = isFavorite;
|
||||
|
@ -567,10 +565,8 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
|
||||
var item = string.IsNullOrEmpty(itemId) ? user.RootFolder : _libraryManager.GetItemById(itemId);
|
||||
|
||||
var key = item.GetUserDataKey();
|
||||
|
||||
// Get the user data for this item
|
||||
var data = _userDataRepository.GetUserData(user.Id, key);
|
||||
var data = _userDataRepository.GetUserData(user, item);
|
||||
|
||||
data.Likes = likes;
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ namespace MediaBrowser.Api
|
|||
var items = request.Ids.Split(',')
|
||||
.Select(i => new Guid(i))
|
||||
.Select(i => _libraryManager.GetItemById(i))
|
||||
.OfType<Video>()
|
||||
.ToList();
|
||||
|
||||
if (items.Count < 2)
|
||||
|
@ -137,14 +138,7 @@ namespace MediaBrowser.Api
|
|||
throw new ArgumentException("Please supply at least two videos to merge.");
|
||||
}
|
||||
|
||||
if (items.Any(i => !(i is Video)))
|
||||
{
|
||||
throw new ArgumentException("Only videos can be grouped together.");
|
||||
}
|
||||
|
||||
var videos = items.Cast<Video>().ToList();
|
||||
|
||||
var videosWithVersions = videos.Where(i => i.MediaSourceCount > 1)
|
||||
var videosWithVersions = items.Where(i => i.MediaSourceCount > 1)
|
||||
.ToList();
|
||||
|
||||
if (videosWithVersions.Count > 1)
|
||||
|
@ -156,7 +150,7 @@ namespace MediaBrowser.Api
|
|||
|
||||
if (primaryVersion == null)
|
||||
{
|
||||
primaryVersion = videos.OrderBy(i =>
|
||||
primaryVersion = items.OrderBy(i =>
|
||||
{
|
||||
if (i.Video3DFormat.HasValue)
|
||||
{
|
||||
|
@ -179,7 +173,7 @@ namespace MediaBrowser.Api
|
|||
}).First();
|
||||
}
|
||||
|
||||
foreach (var item in videos.Where(i => i.Id != primaryVersion.Id))
|
||||
foreach (var item in items.Where(i => i.Id != primaryVersion.Id))
|
||||
{
|
||||
item.PrimaryVersionId = primaryVersion.Id;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
IArchivable
|
||||
{
|
||||
public List<ChannelMediaInfo> ChannelMediaSources { get; set; }
|
||||
|
||||
|
||||
public long? Size { get; set; }
|
||||
public string Container { get; set; }
|
||||
public int? TotalBitrate { get; set; }
|
||||
|
@ -150,12 +150,10 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
+ (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
if (ConfigurationManager.Configuration.EnableStandaloneMusicKeys)
|
||||
{
|
||||
var songKey = IndexNumber.HasValue ? IndexNumber.Value.ToString("0000") : string.Empty;
|
||||
|
@ -165,7 +163,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
{
|
||||
songKey = ParentIndexNumber.Value.ToString("0000") + "-" + songKey;
|
||||
}
|
||||
songKey+= Name;
|
||||
songKey += Name;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Album))
|
||||
{
|
||||
|
@ -178,25 +176,25 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
songKey = albumArtist + "-" + songKey;
|
||||
}
|
||||
|
||||
return songKey;
|
||||
list.Insert(0, songKey);
|
||||
}
|
||||
|
||||
var parent = AlbumEntity;
|
||||
|
||||
if (parent != null)
|
||||
else
|
||||
{
|
||||
var parentKey = parent.GetUserDataKey();
|
||||
var parent = AlbumEntity;
|
||||
|
||||
if (IndexNumber.HasValue)
|
||||
if (parent != null && IndexNumber.HasValue)
|
||||
{
|
||||
var songKey = (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("0000 - ") : "")
|
||||
+ IndexNumber.Value.ToString("0000 - ");
|
||||
list.InsertRange(0, parent.GetUserDataKeys().Select(i =>
|
||||
{
|
||||
var songKey = (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("0000 - ") : "")
|
||||
+ IndexNumber.Value.ToString("0000 - ");
|
||||
|
||||
return parentKey + songKey;
|
||||
return i + songKey;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return base.CreateUserDataKey();
|
||||
return list;
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
|
|
|
@ -96,36 +96,34 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
|
||||
public List<string> Artists { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var id = this.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(id))
|
||||
{
|
||||
return "MusicAlbum-MusicBrainzReleaseGroup-" + id;
|
||||
}
|
||||
|
||||
id = this.GetProviderId(MetadataProviders.MusicBrainzAlbum);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(id))
|
||||
{
|
||||
return "MusicAlbum-Musicbrainz-" + id;
|
||||
}
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
if (ConfigurationManager.Configuration.EnableStandaloneMusicKeys)
|
||||
{
|
||||
var albumArtist = AlbumArtist;
|
||||
if (!string.IsNullOrWhiteSpace(albumArtist))
|
||||
{
|
||||
return albumArtist + "-" + Name;
|
||||
list.Insert(0, albumArtist + "-" + Name);
|
||||
}
|
||||
}
|
||||
|
||||
return base.CreateUserDataKey();
|
||||
var id = this.GetProviderId(MetadataProviders.MusicBrainzAlbum);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(id))
|
||||
{
|
||||
list.Insert(0, "MusicAlbum-Musicbrainz-" + id);
|
||||
}
|
||||
|
||||
id = this.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(id))
|
||||
{
|
||||
list.Insert(0, "MusicAlbum-MusicBrainzReleaseGroup-" + id);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
|
|
|
@ -80,13 +80,12 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
ProductionLocations = new List<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
return GetUserDataKey(this);
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.InsertRange(0, GetUserDataKeys(this));
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -121,16 +120,18 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private static string GetUserDataKey(MusicArtist item)
|
||||
private static List<string> GetUserDataKeys(MusicArtist item)
|
||||
{
|
||||
var list = new List<string>();
|
||||
var id = item.GetProviderId(MetadataProviders.MusicBrainzArtist);
|
||||
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
return "Artist-Musicbrainz-" + id;
|
||||
list.Add("Artist-Musicbrainz-" + id);
|
||||
}
|
||||
|
||||
return "Artist-" + item.Name;
|
||||
list.Add("Artist-" + item.Name);
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
|
|
|
@ -10,13 +10,12 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
/// </summary>
|
||||
public class MusicGenre : BaseItem, IItemByName
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
return "MusicGenre-" + Name;
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, "MusicGenre-" + Name);
|
||||
return list;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
|
|
|
@ -1149,6 +1149,12 @@ namespace MediaBrowser.Controller.Entities
|
|||
get { return null; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public virtual string PresentationUniqueKey
|
||||
{
|
||||
get { return Id.ToString("N"); }
|
||||
}
|
||||
|
||||
private string _userDataKey;
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
|
@ -1158,7 +1164,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
if (string.IsNullOrWhiteSpace(_userDataKey))
|
||||
{
|
||||
var key = CreateUserDataKey();
|
||||
var key = GetUserDataKeys().First();
|
||||
_userDataKey = key;
|
||||
return key;
|
||||
}
|
||||
|
@ -1166,16 +1172,20 @@ namespace MediaBrowser.Controller.Entities
|
|||
return _userDataKey;
|
||||
}
|
||||
|
||||
protected virtual string CreateUserDataKey()
|
||||
public virtual List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
if (SourceType == SourceType.Channel)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(ExternalId))
|
||||
{
|
||||
return ExternalId;
|
||||
list.Add(ExternalId);
|
||||
}
|
||||
}
|
||||
return Id.ToString();
|
||||
|
||||
list.Add(Id.ToString());
|
||||
return list;
|
||||
}
|
||||
|
||||
internal virtual bool IsValidFromResolver(BaseItem newItem)
|
||||
|
@ -1617,9 +1627,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
var key = GetUserDataKey();
|
||||
|
||||
var data = UserDataManager.GetUserData(user.Id, key);
|
||||
var data = UserDataManager.GetUserData(user, this);
|
||||
|
||||
if (datePlayed.HasValue)
|
||||
{
|
||||
|
@ -1654,9 +1662,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
var key = GetUserDataKey();
|
||||
|
||||
var data = UserDataManager.GetUserData(user.Id, key);
|
||||
var data = UserDataManager.GetUserData(user, this);
|
||||
|
||||
//I think it is okay to do this here.
|
||||
// if this is only called when a user is manually forcing something to un-played
|
||||
|
@ -1987,14 +1993,14 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
public virtual bool IsPlayed(User user)
|
||||
{
|
||||
var userdata = UserDataManager.GetUserData(user.Id, GetUserDataKey());
|
||||
var userdata = UserDataManager.GetUserData(user, this);
|
||||
|
||||
return userdata != null && userdata.Played;
|
||||
}
|
||||
|
||||
public bool IsFavoriteOrLiked(User user)
|
||||
{
|
||||
var userdata = UserDataManager.GetUserData(user.Id, GetUserDataKey());
|
||||
var userdata = UserDataManager.GetUserData(user, this);
|
||||
|
||||
return userdata != null && (userdata.IsFavorite || (userdata.Likes ?? false));
|
||||
}
|
||||
|
@ -2006,7 +2012,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
throw new ArgumentNullException("user");
|
||||
}
|
||||
|
||||
var userdata = UserDataManager.GetUserData(user.Id, GetUserDataKey());
|
||||
var userdata = UserDataManager.GetUserData(user, this);
|
||||
|
||||
return userdata == null || !userdata.Played;
|
||||
}
|
||||
|
|
|
@ -839,11 +839,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
Logger.Debug("Query requires post-filtering due to ItemSortBy.SeriesSortName");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.StartDate, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.StartDate");
|
||||
return true;
|
||||
}
|
||||
if (query.SortBy.Contains(ItemSortBy.Studio, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to ItemSortBy.Studio");
|
||||
|
@ -1059,30 +1054,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(query.NameContains))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to NameContains");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(query.NameLessThan))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to NameLessThan");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(query.NameStartsWith))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to NameStartsWith");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(query.NameStartsWithOrGreater))
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to NameStartsWithOrGreater");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (query.AirDays.Length > 0)
|
||||
{
|
||||
Logger.Debug("Query requires post-filtering due to AirDays");
|
||||
|
@ -1635,7 +1606,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
var isUnplayed = true;
|
||||
|
||||
var itemUserData = UserDataManager.GetUserData(user.Id, child.GetUserDataKey());
|
||||
var itemUserData = UserDataManager.GetUserData(user, child);
|
||||
|
||||
// Incrememt totalPercentPlayed
|
||||
if (itemUserData != null)
|
||||
|
|
|
@ -76,15 +76,16 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// </summary>
|
||||
public List<string> MultiPartGameFiles { get; set; }
|
||||
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
var id = this.GetProviderId(MetadataProviders.Gamesdb);
|
||||
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
return "Game-Gamesdb-" + id;
|
||||
list.Insert(0, "Game-Gamesdb-" + id);
|
||||
}
|
||||
return base.CreateUserDataKey();
|
||||
return list;
|
||||
}
|
||||
|
||||
public override IEnumerable<string> GetDeletePaths()
|
||||
|
|
|
@ -7,13 +7,12 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
public class GameGenre : BaseItem, IItemByName
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
return "GameGenre-" + Name;
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, "GameGenre-" + Name);
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
|
@ -31,17 +32,15 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// <value>The game system.</value>
|
||||
public string GameSystemName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
if (!string.IsNullOrEmpty(GameSystemName))
|
||||
{
|
||||
return "GameSystem-" + GameSystemName;
|
||||
list.Insert(0, "GameSystem-" + GameSystemName);
|
||||
}
|
||||
return base.CreateUserDataKey();
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
|
|
|
@ -11,13 +11,12 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// </summary>
|
||||
public class Genre : BaseItem, IItemByName
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
return "Genre-" + Name;
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, "Genre-" + Name);
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Model.Dto;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
|
@ -13,6 +14,8 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// <returns>System.String.</returns>
|
||||
string GetUserDataKey();
|
||||
|
||||
List<string> GetUserDataKeys();
|
||||
|
||||
/// <summary>
|
||||
/// Fills the user data dto values.
|
||||
/// </summary>
|
||||
|
|
|
@ -46,6 +46,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
public string NameLessThan { get; set; }
|
||||
public string NameContains { get; set; }
|
||||
|
||||
public string PresentationUniqueKey { get; set; }
|
||||
public string Path { get; set; }
|
||||
|
||||
public string Person { get; set; }
|
||||
|
|
|
@ -75,34 +75,6 @@ namespace MediaBrowser.Controller.Entities.Movies
|
|||
get { return TmdbCollectionName; }
|
||||
set { TmdbCollectionName = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
{
|
||||
var key = GetMovieUserDataKey(this);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
key = base.CreateUserDataKey();
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
public static string GetMovieUserDataKey(BaseItem movie)
|
||||
{
|
||||
var key = movie.GetProviderId(MetadataProviders.Tmdb);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
key = movie.GetProviderId(MetadataProviders.Imdb);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
|
||||
{
|
||||
|
|
|
@ -44,15 +44,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
{
|
||||
return this.GetProviderId(MetadataProviders.Tmdb) ?? this.GetProviderId(MetadataProviders.Imdb) ?? base.CreateUserDataKey();
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Music;
|
||||
|
|
|
@ -18,13 +18,12 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// <value>The place of birth.</value>
|
||||
public string PlaceOfBirth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
return "Person-" + Name;
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, "Person-" + Name);
|
||||
return list;
|
||||
}
|
||||
|
||||
public PersonLookupInfo GetLookupInfo()
|
||||
|
|
|
@ -10,13 +10,12 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// </summary>
|
||||
public class Studio : BaseItem, IItemByName, IHasTags
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
return "Studio-" + Name;
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, "Studio-" + Name);
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -58,25 +58,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
{
|
||||
get
|
||||
{
|
||||
return AirsAfterSeasonNumber ?? AirsBeforeSeasonNumber ?? PhysicalSeasonNumber;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public int? PhysicalSeasonNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
var value = ParentIndexNumber;
|
||||
|
||||
if (value.HasValue)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
var season = Season;
|
||||
|
||||
return season != null ? season.IndexNumber : null;
|
||||
return AirsAfterSeasonNumber ?? AirsBeforeSeasonNumber ?? ParentIndexNumber;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,20 +80,26 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
[IgnoreDataMember]
|
||||
protected override bool EnableDefaultVideoUserDataKeys
|
||||
{
|
||||
var series = Series;
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
var series = Series;
|
||||
if (series != null && ParentIndexNumber.HasValue && IndexNumber.HasValue)
|
||||
{
|
||||
return series.GetUserDataKey() + ParentIndexNumber.Value.ToString("000") + IndexNumber.Value.ToString("000");
|
||||
list.InsertRange(0, series.GetUserDataKeys().Select(i => i + ParentIndexNumber.Value.ToString("000") + IndexNumber.Value.ToString("000")));
|
||||
}
|
||||
|
||||
return base.CreateUserDataKey();
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -310,6 +298,19 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
Logger.ErrorException("Error in FillMissingEpisodeNumbersFromPath. Episode: {0}", ex, Path ?? Name ?? Id.ToString());
|
||||
}
|
||||
|
||||
if (!ParentIndexNumber.HasValue)
|
||||
{
|
||||
var season = Season;
|
||||
if (season != null)
|
||||
{
|
||||
if (season.ParentIndexNumber.HasValue)
|
||||
{
|
||||
ParentIndexNumber = season.ParentIndexNumber;
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,19 +53,17 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
if (Series != null)
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
var series = Series;
|
||||
if (series != null)
|
||||
{
|
||||
var seasonNo = IndexNumber ?? 0;
|
||||
return Series.GetUserDataKey() + seasonNo.ToString("000");
|
||||
list.InsertRange(0, series.GetUserDataKeys().Select(i => i + (IndexNumber ?? 0).ToString("000")));
|
||||
}
|
||||
|
||||
return base.CreateUserDataKey();
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -94,6 +92,24 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override string PresentationUniqueKey
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IndexNumber.HasValue)
|
||||
{
|
||||
var series = Series;
|
||||
if (series != null)
|
||||
{
|
||||
return series.PresentationUniqueKey + "-" + (IndexNumber ?? 0).ToString("000");
|
||||
}
|
||||
}
|
||||
|
||||
return base.PresentationUniqueKey;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the name of the sort.
|
||||
/// </summary>
|
||||
|
@ -171,16 +187,16 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
|
||||
public IEnumerable<Episode> GetEpisodes(User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
|
||||
{
|
||||
var episodes = GetRecursiveChildren(user)
|
||||
.OfType<Episode>();
|
||||
|
||||
var series = Series;
|
||||
|
||||
if (IndexNumber.HasValue && series != null)
|
||||
{
|
||||
return series.GetEpisodes(user, IndexNumber.Value, includeMissingEpisodes, includeVirtualUnairedEpisodes, episodes);
|
||||
return series.GetEpisodes(user, IndexNumber.Value, includeMissingEpisodes, includeVirtualUnairedEpisodes);
|
||||
}
|
||||
|
||||
var episodes = GetRecursiveChildren(user)
|
||||
.OfType<Episode>();
|
||||
|
||||
if (series != null && series.ContainsEpisodesWithoutSeasonFolders)
|
||||
{
|
||||
var seasonNumber = IndexNumber;
|
||||
|
|
|
@ -91,25 +91,33 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override string PresentationUniqueKey
|
||||
{
|
||||
get { return GetUserDataKeys().First(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var key = this.GetProviderId(MetadataProviders.Tvdb);
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
var key = this.GetProviderId(MetadataProviders.Imdb);
|
||||
if (!string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
key = this.GetProviderId(MetadataProviders.Imdb);
|
||||
list.Insert(0, key);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
key = this.GetProviderId(MetadataProviders.Tvdb);
|
||||
if (!string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
key = base.CreateUserDataKey();
|
||||
list.Insert(0, key);
|
||||
}
|
||||
|
||||
return key;
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -126,8 +134,8 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
// Studio, Genre and Rating will all be the same so makes no sense to index by these
|
||||
protected override IEnumerable<string> GetIndexByOptions()
|
||||
{
|
||||
return new List<string> {
|
||||
{"None"},
|
||||
return new List<string> {
|
||||
{"None"},
|
||||
{"Performer"},
|
||||
{"Director"},
|
||||
{"Year"},
|
||||
|
@ -183,8 +191,28 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
|
||||
public IEnumerable<Season> GetSeasons(User user, bool includeMissingSeasons, bool includeVirtualUnaired)
|
||||
{
|
||||
var seasons = base.GetChildren(user, true)
|
||||
.OfType<Season>();
|
||||
var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user)
|
||||
{
|
||||
PresentationUniqueKey = PresentationUniqueKey,
|
||||
IncludeItemTypes = new[] { typeof(Series).Name }
|
||||
});
|
||||
|
||||
IEnumerable<Season> seasons;
|
||||
|
||||
if (seriesIds.Count > 1)
|
||||
{
|
||||
seasons = LibraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(),
|
||||
IncludeItemTypes = new[] { typeof(Season).Name },
|
||||
SortBy = new[] { ItemSortBy.SortName }
|
||||
|
||||
}).OfType<Season>();
|
||||
}
|
||||
else
|
||||
{
|
||||
seasons = base.GetChildren(user, true).OfType<Season>();
|
||||
}
|
||||
|
||||
if (!includeMissingSeasons && !includeVirtualUnaired)
|
||||
{
|
||||
|
@ -202,9 +230,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
}
|
||||
}
|
||||
|
||||
return LibraryManager
|
||||
.Sort(seasons, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending)
|
||||
.Cast<Season>();
|
||||
return seasons;
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetEpisodes(User user)
|
||||
|
@ -280,9 +306,9 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
if (episode != null
|
||||
&& refreshOptions.MetadataRefreshMode != MetadataRefreshMode.FullRefresh
|
||||
&& !refreshOptions.ReplaceAllMetadata
|
||||
&& episode.IsMissingEpisode
|
||||
&& episode.LocationType == Model.Entities.LocationType.Virtual
|
||||
&& episode.PremiereDate.HasValue
|
||||
&& episode.IsMissingEpisode
|
||||
&& episode.LocationType == Model.Entities.LocationType.Virtual
|
||||
&& episode.PremiereDate.HasValue
|
||||
&& (DateTime.UtcNow - episode.PremiereDate.Value).TotalDays > 30)
|
||||
{
|
||||
skipItem = true;
|
||||
|
@ -313,19 +339,32 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
|
||||
public IEnumerable<Episode> GetEpisodes(User user, int seasonNumber, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
|
||||
{
|
||||
return GetEpisodes(user, seasonNumber, includeMissingEpisodes, includeVirtualUnairedEpisodes,
|
||||
new List<Episode>());
|
||||
}
|
||||
var seriesIds = LibraryManager.GetItemIds(new InternalItemsQuery(user)
|
||||
{
|
||||
PresentationUniqueKey = PresentationUniqueKey,
|
||||
IncludeItemTypes = new[] { typeof(Series).Name }
|
||||
});
|
||||
|
||||
internal IEnumerable<Episode> GetEpisodes(User user, int seasonNumber, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable<Episode> additionalEpisodes)
|
||||
{
|
||||
var episodes = GetRecursiveChildren(user, i => i is Episode)
|
||||
.Cast<Episode>();
|
||||
IEnumerable<Episode> episodes;
|
||||
|
||||
if (seriesIds.Count > 1)
|
||||
{
|
||||
episodes = LibraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
AncestorIds = seriesIds.Select(i => i.ToString("N")).ToArray(),
|
||||
IncludeItemTypes = new[] { typeof(Episode).Name },
|
||||
SortBy = new[] { ItemSortBy.SortName }
|
||||
|
||||
}).OfType<Episode>();
|
||||
}
|
||||
else
|
||||
{
|
||||
episodes = GetRecursiveChildren(user, i => i is Episode)
|
||||
.Cast<Episode>();
|
||||
}
|
||||
|
||||
episodes = FilterEpisodesBySeason(episodes, seasonNumber, DisplaySpecialsWithSeasons);
|
||||
|
||||
episodes = episodes.Concat(additionalEpisodes).Distinct();
|
||||
|
||||
if (!includeMissingEpisodes)
|
||||
{
|
||||
episodes = episodes.Where(i => !i.IsMissingEpisode);
|
||||
|
@ -352,7 +391,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
{
|
||||
if (!includeSpecials || seasonNumber < 1)
|
||||
{
|
||||
return episodes.Where(i => (i.PhysicalSeasonNumber ?? -1) == seasonNumber);
|
||||
return episodes.Where(i => (i.ParentIndexNumber ?? -1) == seasonNumber);
|
||||
}
|
||||
|
||||
return episodes.Where(i =>
|
||||
|
|
|
@ -56,26 +56,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// <value>The revenue.</value>
|
||||
public double? Revenue { get; set; }
|
||||
|
||||
protected override string CreateUserDataKey()
|
||||
{
|
||||
var key = Movie.GetMovieUserDataKey(this);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
key = key + "-trailer";
|
||||
|
||||
// Make sure different trailers have their own data.
|
||||
if (RunTimeTicks.HasValue)
|
||||
{
|
||||
key += "-" + RunTimeTicks.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
return base.CreateUserDataKey();
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Trailer;
|
||||
|
|
|
@ -348,7 +348,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
.Where(i => !i.IsFolder)
|
||||
.OfType<IHasAlbumArtist>();
|
||||
|
||||
var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite);
|
||||
var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user, i).IsFavorite);
|
||||
|
||||
return GetResult(artists, parent, query);
|
||||
}
|
||||
|
@ -1218,7 +1218,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
if (query.IsLiked.HasValue)
|
||||
{
|
||||
userData = userData ?? userDataManager.GetUserData(user.Id, item.GetUserDataKey());
|
||||
userData = userData ?? userDataManager.GetUserData(user, item);
|
||||
|
||||
if (!userData.Likes.HasValue || userData.Likes != query.IsLiked.Value)
|
||||
{
|
||||
|
@ -1228,7 +1228,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
if (query.IsFavoriteOrLiked.HasValue)
|
||||
{
|
||||
userData = userData ?? userDataManager.GetUserData(user.Id, item.GetUserDataKey());
|
||||
userData = userData ?? userDataManager.GetUserData(user, item);
|
||||
var isFavoriteOrLiked = userData.IsFavorite || (userData.Likes ?? false);
|
||||
|
||||
if (isFavoriteOrLiked != query.IsFavoriteOrLiked.Value)
|
||||
|
@ -1239,7 +1239,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
if (query.IsFavorite.HasValue)
|
||||
{
|
||||
userData = userData ?? userDataManager.GetUserData(user.Id, item.GetUserDataKey());
|
||||
userData = userData ?? userDataManager.GetUserData(user, item);
|
||||
|
||||
if (userData.IsFavorite != query.IsFavorite.Value)
|
||||
{
|
||||
|
@ -1249,7 +1249,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
if (query.IsResumable.HasValue)
|
||||
{
|
||||
userData = userData ?? userDataManager.GetUserData(user.Id, item.GetUserDataKey());
|
||||
userData = userData ?? userDataManager.GetUserData(user, item);
|
||||
var isResumable = userData.PlaybackPositionTicks > 0;
|
||||
|
||||
if (isResumable != query.IsResumable.Value)
|
||||
|
|
|
@ -44,6 +44,20 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override string PresentationUniqueKey
|
||||
{
|
||||
get
|
||||
{
|
||||
if (PrimaryVersionId.HasValue)
|
||||
{
|
||||
return PrimaryVersionId.Value.ToString("N");
|
||||
}
|
||||
|
||||
return base.PresentationUniqueKey;
|
||||
}
|
||||
}
|
||||
|
||||
public long? Size { get; set; }
|
||||
public string Container { get; set; }
|
||||
public int? TotalBitrate { get; set; }
|
||||
|
@ -90,6 +104,14 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
get
|
||||
{
|
||||
if (PrimaryVersionId.HasValue)
|
||||
{
|
||||
var item = LibraryManager.GetItemById(PrimaryVersionId.Value) as Video;
|
||||
if (item != null)
|
||||
{
|
||||
return item.MediaSourceCount;
|
||||
}
|
||||
}
|
||||
return LinkedAlternateVersions.Count + LocalAlternateVersions.Count + 1;
|
||||
}
|
||||
}
|
||||
|
@ -131,42 +153,65 @@ namespace MediaBrowser.Controller.Entities
|
|||
return LocalAlternateVersions.Select(i => LibraryManager.GetNewItemId(i, typeof(Video)));
|
||||
}
|
||||
|
||||
protected override string CreateUserDataKey()
|
||||
[IgnoreDataMember]
|
||||
protected virtual bool EnableDefaultVideoUserDataKeys
|
||||
{
|
||||
if (ExtraType.HasValue)
|
||||
get
|
||||
{
|
||||
var key = this.GetProviderId(MetadataProviders.Imdb) ?? this.GetProviderId(MetadataProviders.Tmdb);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(key))
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
if (EnableDefaultVideoUserDataKeys)
|
||||
{
|
||||
if (ExtraType.HasValue)
|
||||
{
|
||||
key = key + "-" + ExtraType.ToString().ToLower();
|
||||
|
||||
// Make sure different trailers have their own data.
|
||||
if (RunTimeTicks.HasValue)
|
||||
var key = this.GetProviderId(MetadataProviders.Tmdb);
|
||||
if (!string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
key += "-" + RunTimeTicks.Value.ToString(CultureInfo.InvariantCulture);
|
||||
list.Insert(0, GetUserDataKey(key));
|
||||
}
|
||||
|
||||
return key;
|
||||
key = this.GetProviderId(MetadataProviders.Imdb);
|
||||
if (!string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
list.Insert(0, GetUserDataKey(key));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var key = this.GetProviderId(MetadataProviders.Imdb);
|
||||
if (!string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
list.Insert(0, key);
|
||||
}
|
||||
|
||||
key = this.GetProviderId(MetadataProviders.Tmdb);
|
||||
if (!string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
list.Insert(0, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return base.CreateUserDataKey();
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the linked children.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
public IEnumerable<Video> GetAlternateVersions()
|
||||
private string GetUserDataKey(string providerId)
|
||||
{
|
||||
var filesWithinSameDirectory = GetLocalAlternateVersionIds()
|
||||
.Select(i => LibraryManager.GetItemById(i))
|
||||
.Where(i => i != null)
|
||||
.OfType<Video>();
|
||||
var key = providerId + "-" + ExtraType.ToString().ToLower();
|
||||
|
||||
return filesWithinSameDirectory.Concat(GetLinkedAlternateVersions())
|
||||
.OrderBy(i => i.SortName);
|
||||
// Make sure different trailers have their own data.
|
||||
if (RunTimeTicks.HasValue)
|
||||
{
|
||||
key += "-" + RunTimeTicks.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
public IEnumerable<Video> GetLinkedAlternateVersions()
|
||||
|
@ -468,6 +513,36 @@ namespace MediaBrowser.Controller.Entities
|
|||
}).FirstOrDefault();
|
||||
}
|
||||
|
||||
private List<Tuple<Video, MediaSourceType>> GetAllVideosForMediaSources()
|
||||
{
|
||||
var list = new List<Tuple<Video, MediaSourceType>>();
|
||||
|
||||
list.Add(new Tuple<Video, MediaSourceType>(this, MediaSourceType.Default));
|
||||
list.AddRange(GetLinkedAlternateVersions().Select(i => new Tuple<Video, MediaSourceType>(i, MediaSourceType.Grouping)));
|
||||
|
||||
if (PrimaryVersionId.HasValue)
|
||||
{
|
||||
var primary = LibraryManager.GetItemById(PrimaryVersionId.Value) as Video;
|
||||
if (primary != null)
|
||||
{
|
||||
var existingIds = list.Select(i => i.Item1.Id).ToList();
|
||||
list.Add(new Tuple<Video, MediaSourceType>(primary, MediaSourceType.Grouping));
|
||||
list.AddRange(primary.GetLinkedAlternateVersions().Where(i => !existingIds.Contains(i.Id)).Select(i => new Tuple<Video, MediaSourceType>(i, MediaSourceType.Grouping)));
|
||||
}
|
||||
}
|
||||
|
||||
var localAlternates = list
|
||||
.SelectMany(i => i.Item1.GetLocalAlternateVersionIds())
|
||||
.Select(LibraryManager.GetItemById)
|
||||
.Where(i => i != null)
|
||||
.OfType<Video>()
|
||||
.ToList();
|
||||
|
||||
list.AddRange(localAlternates.Select(i => new Tuple<Video, MediaSourceType>(i, MediaSourceType.Default)));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public virtual IEnumerable<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
{
|
||||
if (SourceType == SourceType.Channel)
|
||||
|
@ -486,13 +561,8 @@ namespace MediaBrowser.Controller.Entities
|
|||
};
|
||||
}
|
||||
|
||||
var item = this;
|
||||
|
||||
var result = item.GetAlternateVersions()
|
||||
.Select(i => GetVersionInfo(enablePathSubstitution, i, MediaSourceType.Grouping))
|
||||
.ToList();
|
||||
|
||||
result.Add(GetVersionInfo(enablePathSubstitution, item, MediaSourceType.Default));
|
||||
var list = GetAllVideosForMediaSources();
|
||||
var result = list.Select(i => GetVersionInfo(enablePathSubstitution, i.Item1, i.Item2)).ToList();
|
||||
|
||||
return result.OrderBy(i =>
|
||||
{
|
||||
|
|
|
@ -11,13 +11,12 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// </summary>
|
||||
public class Year : BaseItem, IItemByName
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
return "Year-" + Name;
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, "Year-" + Name);
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -45,6 +45,11 @@ namespace MediaBrowser.Controller.Library
|
|||
/// <returns>Task{UserItemData}.</returns>
|
||||
UserItemData GetUserData(Guid userId, string key);
|
||||
|
||||
UserItemData GetUserData(IHasUserData user, IHasUserData item);
|
||||
|
||||
UserItemData GetUserData(string userId, IHasUserData item);
|
||||
UserItemData GetUserData(Guid userId, IHasUserData item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data dto.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
|
@ -15,11 +16,7 @@ namespace MediaBrowser.Controller.Library
|
|||
/// <value>The user id.</value>
|
||||
public Guid UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the key.
|
||||
/// </summary>
|
||||
/// <value>The key.</value>
|
||||
public string Key { get; set; }
|
||||
public List<string> Keys { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the save reason.
|
||||
|
|
|
@ -45,17 +45,6 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
set { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
{
|
||||
var name = GetClientTypeName();
|
||||
|
||||
return name + "-" + Name + (EpisodeTitle ?? string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is owned item.
|
||||
/// </summary>
|
||||
|
|
|
@ -11,13 +11,12 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
{
|
||||
public class LiveTvChannel : BaseItem, IHasMediaSources
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
return GetClientTypeName() + "-" + Name;
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, GetClientTypeName() + "-" + Name);
|
||||
return list;
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
|
|
|
@ -4,36 +4,40 @@ using MediaBrowser.Controller.Providers;
|
|||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
public class LiveTvProgram : BaseItem, IHasLookupInfo<LiveTvProgramLookupInfo>, IHasStartDate, IHasProgramAttributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
if (IsMovie)
|
||||
{
|
||||
var key = Movie.GetMovieUserDataKey(this);
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
if (!IsSeries)
|
||||
{
|
||||
var key = this.GetProviderId(MetadataProviders.Imdb);
|
||||
if (!string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
return key;
|
||||
list.Insert(0, key);
|
||||
}
|
||||
|
||||
key = this.GetProviderId(MetadataProviders.Tmdb);
|
||||
if (!string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
list.Insert(0, key);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsSeries && !string.IsNullOrWhiteSpace(EpisodeTitle))
|
||||
else if (!string.IsNullOrWhiteSpace(EpisodeTitle))
|
||||
{
|
||||
var name = GetClientTypeName();
|
||||
|
||||
return name + "-" + Name + (EpisodeTitle ?? string.Empty);
|
||||
list.Insert(0, name + "-" + Name + (EpisodeTitle ?? string.Empty));
|
||||
}
|
||||
|
||||
return base.CreateUserDataKey();
|
||||
return list;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
|
|
|
@ -45,32 +45,6 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
set { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateUserDataKey()
|
||||
{
|
||||
if (IsMovie)
|
||||
{
|
||||
var key = Movie.GetMovieUserDataKey(this);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsSeries && !string.IsNullOrWhiteSpace(EpisodeTitle))
|
||||
{
|
||||
var name = GetClientTypeName();
|
||||
|
||||
return name + "-" + Name + (EpisodeTitle ?? string.Empty);
|
||||
}
|
||||
|
||||
return base.CreateUserDataKey();
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override string MediaType
|
||||
{
|
||||
|
|
|
@ -19,12 +19,6 @@ namespace MediaBrowser.Controller.Notifications
|
|||
/// Occurs when [notifications marked read].
|
||||
/// </summary>
|
||||
event EventHandler<NotificationReadEventArgs> NotificationsMarkedRead;
|
||||
|
||||
/// <summary>
|
||||
/// Opens the connection to the repository
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
Task Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the notifications.
|
||||
|
|
|
@ -11,12 +11,6 @@ namespace MediaBrowser.Controller.Persistence
|
|||
/// </summary>
|
||||
public interface IDisplayPreferencesRepository : IRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Opens the connection to the repository
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
Task Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// Saves display preferences for an item
|
||||
/// </summary>
|
||||
|
|
|
@ -13,12 +13,6 @@ namespace MediaBrowser.Controller.Persistence
|
|||
/// </summary>
|
||||
public interface IItemRepository : IRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Opens the connection to the repository
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
Task Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// Saves an item
|
||||
/// </summary>
|
||||
|
|
|
@ -11,12 +11,6 @@ namespace MediaBrowser.Controller.Persistence
|
|||
/// </summary>
|
||||
public interface IUserDataRepository : IRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Opens the connection to the repository
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
Task Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// Saves the user data.
|
||||
/// </summary>
|
||||
|
|
|
@ -21,11 +21,5 @@ namespace MediaBrowser.Controller.Providers
|
|||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveMetadataStatus(MetadataStatus status, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this instance.
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
Task Initialize();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
|||
|
||||
var newbookmark = int.Parse(sparams["PosSecond"], _usCulture);
|
||||
|
||||
var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
|
||||
var userdata = _userDataManager.GetUserData(user, item);
|
||||
|
||||
userdata.PlaybackPositionTicks = TimeSpan.FromSeconds(newbookmark).Ticks;
|
||||
|
||||
|
|
|
@ -201,6 +201,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
public string[] Migrations { get; set; }
|
||||
|
||||
public int MigrationVersion { get; set; }
|
||||
public int SchemaVersion { get; set; }
|
||||
|
||||
public bool DownloadImagesInAdvance { get; set; }
|
||||
|
||||
|
|
|
@ -444,7 +444,11 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||
{
|
||||
if (string.IsNullOrWhiteSpace(video.Name) || string.Equals(video.Name, Path.GetFileNameWithoutExtension(video.Path), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
video.Name = data.Name;
|
||||
// Don't use the embedded name for extras because it will often be the same name as the movie
|
||||
if (!video.ExtraType.HasValue && !video.IsOwnedItem)
|
||||
{
|
||||
video.Name = data.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,11 +27,11 @@ namespace MediaBrowser.Server.Implementations.Activity
|
|||
_appPaths = appPaths;
|
||||
}
|
||||
|
||||
public async Task Initialize()
|
||||
public async Task Initialize(IDbConnector dbConnector)
|
||||
{
|
||||
var dbFile = Path.Combine(_appPaths.DataPath, "activitylog.db");
|
||||
|
||||
_connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
|
||||
_connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
|
||||
|
||||
string[] queries = {
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
if (query.IsFavorite.HasValue)
|
||||
{
|
||||
var val = query.IsFavorite.Value;
|
||||
channels = channels.Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite == val)
|
||||
channels = channels.Where(i => _userDataManager.GetUserData(user, i).IsFavorite == val)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
@ -1437,7 +1437,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
case ItemFilter.IsFavoriteOrLikes:
|
||||
return items.Where(item =>
|
||||
{
|
||||
var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
|
||||
var userdata = _userDataManager.GetUserData(user, item);
|
||||
|
||||
if (userdata == null)
|
||||
{
|
||||
|
@ -1453,7 +1453,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
case ItemFilter.Likes:
|
||||
return items.Where(item =>
|
||||
{
|
||||
var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
|
||||
var userdata = _userDataManager.GetUserData(user, item);
|
||||
|
||||
return userdata != null && userdata.Likes.HasValue && userdata.Likes.Value;
|
||||
});
|
||||
|
@ -1461,7 +1461,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
case ItemFilter.Dislikes:
|
||||
return items.Where(item =>
|
||||
{
|
||||
var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
|
||||
var userdata = _userDataManager.GetUserData(user, item);
|
||||
|
||||
return userdata != null && userdata.Likes.HasValue && !userdata.Likes.Value;
|
||||
});
|
||||
|
@ -1469,7 +1469,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
case ItemFilter.IsFavorite:
|
||||
return items.Where(item =>
|
||||
{
|
||||
var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
|
||||
var userdata = _userDataManager.GetUserData(user, item);
|
||||
|
||||
return userdata != null && userdata.IsFavorite;
|
||||
});
|
||||
|
@ -1477,7 +1477,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
case ItemFilter.IsResumable:
|
||||
return items.Where(item =>
|
||||
{
|
||||
var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
|
||||
var userdata = _userDataManager.GetUserData(user, item);
|
||||
|
||||
return userdata != null && userdata.PlaybackPositionTicks > 0;
|
||||
});
|
||||
|
|
|
@ -487,7 +487,7 @@ namespace MediaBrowser.Server.Implementations.Dto
|
|||
{
|
||||
if (item.IsFolder)
|
||||
{
|
||||
var userData = _userDataRepository.GetUserData(user.Id, item.GetUserDataKey());
|
||||
var userData = _userDataRepository.GetUserData(user, item);
|
||||
|
||||
// Skip the user data manager because we've already looped through the recursive tree and don't want to do it twice
|
||||
// TODO: Improve in future
|
||||
|
@ -1363,9 +1363,10 @@ namespace MediaBrowser.Server.Implementations.Dto
|
|||
|
||||
if (fields.Contains(ItemFields.MediaSourceCount))
|
||||
{
|
||||
if (video.MediaSourceCount != 1)
|
||||
var mediaSourceCount = video.MediaSourceCount;
|
||||
if (mediaSourceCount != 1)
|
||||
{
|
||||
dto.MediaSourceCount = video.MediaSourceCount;
|
||||
dto.MediaSourceCount = mediaSourceCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1686,7 +1687,7 @@ namespace MediaBrowser.Server.Implementations.Dto
|
|||
dateLastMediaAdded = new[] { dateLastMediaAdded.Value, child.DateCreated }.Max();
|
||||
}
|
||||
|
||||
var userdata = _userDataRepository.GetUserData(user.Id, child.GetUserDataKey());
|
||||
var userdata = _userDataRepository.GetUserData(user, child);
|
||||
|
||||
recursiveItemCount++;
|
||||
|
||||
|
|
|
@ -522,29 +522,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
throw new ArgumentNullException("items");
|
||||
}
|
||||
|
||||
var dict = new Dictionary<Guid, BaseItem>();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
var video = item as Video;
|
||||
|
||||
if (video != null)
|
||||
{
|
||||
if (video.PrimaryVersionId.HasValue)
|
||||
{
|
||||
var primary = GetItemById(video.PrimaryVersionId.Value) as Video;
|
||||
|
||||
if (primary != null)
|
||||
{
|
||||
dict[primary.Id] = primary;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
dict[item.Id] = item;
|
||||
}
|
||||
|
||||
return dict.Values;
|
||||
return items.DistinctBy(i => i.PresentationUniqueKey, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -267,7 +267,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
|
||||
private void SetUserProperties(IHasUserData item, MediaSourceInfo source, User user)
|
||||
{
|
||||
var userData = item == null ? new UserItemData() : _userDataManager.GetUserData(user.Id, item.GetUserDataKey());
|
||||
var userData = item == null ? new UserItemData() : _userDataManager.GetUserData(user, item);
|
||||
|
||||
var allowRememberingSelection = item == null || item.EnableRememberingTrackSelections;
|
||||
|
||||
|
|
|
@ -56,27 +56,30 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var key = item.GetUserDataKey();
|
||||
var keys = item.GetUserDataKeys();
|
||||
|
||||
try
|
||||
foreach (var key in keys)
|
||||
{
|
||||
await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var newValue = userData;
|
||||
var newValue = userData;
|
||||
|
||||
// Once it succeeds, put it into the dictionary to make it available to everyone else
|
||||
_userData.AddOrUpdate(GetCacheKey(userId, key), newValue, delegate { return newValue; });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error saving user data", ex);
|
||||
// Once it succeeds, put it into the dictionary to make it available to everyone else
|
||||
_userData.AddOrUpdate(GetCacheKey(userId, key), newValue, delegate { return newValue; });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error saving user data", ex);
|
||||
|
||||
throw;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
EventHelper.FireEventIfNotNull(UserDataSaved, this, new UserDataSaveEventArgs
|
||||
{
|
||||
Key = key,
|
||||
Keys = keys,
|
||||
UserData = userData,
|
||||
SaveReason = reason,
|
||||
UserId = userId,
|
||||
|
@ -172,6 +175,21 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
return userId + key;
|
||||
}
|
||||
|
||||
public UserItemData GetUserData(IHasUserData user, IHasUserData item)
|
||||
{
|
||||
return GetUserData(user.Id, item.GetUserDataKey());
|
||||
}
|
||||
|
||||
public UserItemData GetUserData(string userId, IHasUserData item)
|
||||
{
|
||||
return GetUserData(userId, item.GetUserDataKey());
|
||||
}
|
||||
|
||||
public UserItemData GetUserData(Guid userId, IHasUserData item)
|
||||
{
|
||||
return GetUserData(userId, item.GetUserDataKey());
|
||||
}
|
||||
|
||||
public UserItemDataDto GetUserDataDto(IHasUserData item, User user)
|
||||
{
|
||||
var userData = GetUserData(user.Id, item.GetUserDataKey());
|
||||
|
|
|
@ -164,7 +164,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
var val = query.IsFavorite.Value;
|
||||
|
||||
channels = channels
|
||||
.Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite == val);
|
||||
.Where(i => _userDataManager.GetUserData(user, i).IsFavorite == val);
|
||||
}
|
||||
|
||||
if (query.IsLiked.HasValue)
|
||||
|
@ -174,7 +174,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
channels = channels
|
||||
.Where(i =>
|
||||
{
|
||||
var likes = _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).Likes;
|
||||
var likes = _userDataManager.GetUserData(user, i).Likes;
|
||||
|
||||
return likes.HasValue && likes.Value == val;
|
||||
});
|
||||
|
@ -187,7 +187,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
channels = channels
|
||||
.Where(i =>
|
||||
{
|
||||
var likes = _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).Likes;
|
||||
var likes = _userDataManager.GetUserData(user, i).Likes;
|
||||
|
||||
return likes.HasValue && likes.Value != val;
|
||||
});
|
||||
|
@ -200,7 +200,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
{
|
||||
if (enableFavoriteSorting)
|
||||
{
|
||||
var userData = _userDataManager.GetUserData(user.Id, i.GetUserDataKey());
|
||||
var userData = _userDataManager.GetUserData(user, i);
|
||||
|
||||
if (userData.IsFavorite)
|
||||
{
|
||||
|
@ -1005,7 +1005,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
var channel = GetInternalChannel(program.ChannelId);
|
||||
|
||||
var channelUserdata = _userDataManager.GetUserData(userId, channel.GetUserDataKey());
|
||||
var channelUserdata = _userDataManager.GetUserData(userId, channel);
|
||||
|
||||
if (channelUserdata.Likes ?? false)
|
||||
{
|
||||
|
@ -1036,7 +1036,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
if (genres.TryGetValue(i, out genre))
|
||||
{
|
||||
var genreUserdata = _userDataManager.GetUserData(userId, genre.GetUserDataKey());
|
||||
var genreUserdata = _userDataManager.GetUserData(userId, genre);
|
||||
|
||||
if (genreUserdata.Likes ?? false)
|
||||
{
|
||||
|
|
|
@ -78,9 +78,6 @@
|
|||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.SQLite">
|
||||
<HintPath>..\ThirdParty\System.Data.SQLite.ManagedOnly\1.0.94.0\System.Data.SQLite.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net" />
|
||||
|
@ -261,6 +258,8 @@
|
|||
<Compile Include="Notifications\IConfigurableNotificationService.cs" />
|
||||
<Compile Include="Persistence\BaseSqliteRepository.cs" />
|
||||
<Compile Include="Persistence\CleanDatabaseScheduledTask.cs" />
|
||||
<Compile Include="Persistence\DataExtensions.cs" />
|
||||
<Compile Include="Persistence\IDbConnector.cs" />
|
||||
<Compile Include="Persistence\MediaStreamColumns.cs" />
|
||||
<Compile Include="Social\SharingManager.cs" />
|
||||
<Compile Include="Social\SharingRepository.cs" />
|
||||
|
@ -275,7 +274,6 @@
|
|||
<Compile Include="Notifications\InternalNotificationService.cs" />
|
||||
<Compile Include="Notifications\NotificationConfigurationFactory.cs" />
|
||||
<Compile Include="Notifications\NotificationManager.cs" />
|
||||
<Compile Include="Persistence\SqliteExtensions.cs" />
|
||||
<Compile Include="Persistence\SqliteFileOrganizationRepository.cs" />
|
||||
<Compile Include="Notifications\SqliteNotificationsRepository.cs" />
|
||||
<Compile Include="Persistence\SqliteProviderInfoRepository.cs" />
|
||||
|
|
|
@ -32,11 +32,11 @@ namespace MediaBrowser.Server.Implementations.Notifications
|
|||
_appPaths = appPaths;
|
||||
}
|
||||
|
||||
public async Task Initialize()
|
||||
public async Task Initialize(IDbConnector dbConnector)
|
||||
{
|
||||
var dbFile = Path.Combine(_appPaths.DataPath, "notifications.db");
|
||||
|
||||
_connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
|
||||
_connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
|
||||
|
||||
string[] queries = {
|
||||
|
||||
|
|
|
@ -110,6 +110,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
_config.SaveConfiguration();
|
||||
}
|
||||
|
||||
if (_config.Configuration.SchemaVersion < SqliteItemRepository.LatestSchemaVersion)
|
||||
{
|
||||
_config.Configuration.SchemaVersion = SqliteItemRepository.LatestSchemaVersion;
|
||||
_config.SaveConfiguration();
|
||||
}
|
||||
|
||||
if (EnableUnavailableMessage)
|
||||
{
|
||||
EnableUnavailableMessage = false;
|
||||
|
|
|
@ -3,16 +3,12 @@ using MediaBrowser.Model.Logging;
|
|||
using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.SQLite;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Persistence
|
||||
{
|
||||
/// <summary>
|
||||
/// Class SQLiteExtensions
|
||||
/// </summary>
|
||||
static class SqliteExtensions
|
||||
static class DataExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the specified conn is open.
|
||||
|
@ -28,11 +24,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
{
|
||||
return (IDataParameter)cmd.Parameters[index];
|
||||
}
|
||||
|
||||
|
||||
public static IDataParameter Add(this IDataParameterCollection paramCollection, IDbCommand cmd, string name, DbType type)
|
||||
{
|
||||
var param = cmd.CreateParameter();
|
||||
|
||||
|
||||
param.ParameterName = name;
|
||||
param.DbType = type;
|
||||
|
||||
|
@ -48,11 +44,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
param.ParameterName = name;
|
||||
|
||||
paramCollection.Add(param);
|
||||
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a stream from a DataReader at a given ordinal
|
||||
/// </summary>
|
||||
|
@ -122,38 +118,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Connects to db.
|
||||
/// </summary>
|
||||
/// <param name="dbPath">The db path.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <returns>Task{IDbConnection}.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">dbPath</exception>
|
||||
public static async Task<IDbConnection> ConnectToDb(string dbPath, ILogger logger)
|
||||
{
|
||||
if (string.IsNullOrEmpty(dbPath))
|
||||
{
|
||||
throw new ArgumentNullException("dbPath");
|
||||
}
|
||||
|
||||
logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath);
|
||||
|
||||
var connectionstr = new SQLiteConnectionStringBuilder
|
||||
{
|
||||
PageSize = 4096,
|
||||
CacheSize = 2000,
|
||||
SyncMode = SynchronizationModes.Full,
|
||||
DataSource = dbPath,
|
||||
JournalMode = SQLiteJournalModeEnum.Wal
|
||||
};
|
||||
|
||||
var connection = new SQLiteConnection(connectionstr.ConnectionString);
|
||||
|
||||
await connection.OpenAsync().ConfigureAwait(false);
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
public static void Attach(IDbConnection db, string path, string alias)
|
||||
{
|
||||
using (var cmd = db.CreateCommand())
|
|
@ -0,0 +1,10 @@
|
|||
using System.Data;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Persistence
|
||||
{
|
||||
public interface IDbConnector
|
||||
{
|
||||
Task<IDbConnection> Connect(string dbPath);
|
||||
}
|
||||
}
|
|
@ -52,11 +52,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
/// Opens the connection to the database
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
public async Task Initialize()
|
||||
public async Task Initialize(IDbConnector dbConnector)
|
||||
{
|
||||
var dbFile = Path.Combine(_appPaths.DataPath, "displaypreferences.db");
|
||||
|
||||
_connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
|
||||
_connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
|
||||
|
||||
string[] queries = {
|
||||
|
||||
|
|
|
@ -35,11 +35,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
/// Opens the connection to the database
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
public async Task Initialize()
|
||||
public async Task Initialize(IDbConnector dbConnector)
|
||||
{
|
||||
var dbFile = Path.Combine(_appPaths.DataPath, "fileorganization.db");
|
||||
|
||||
_connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
|
||||
_connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
|
||||
|
||||
string[] queries = {
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Playlists;
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
|
||||
|
@ -55,7 +56,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
/// <summary>
|
||||
/// The _app paths
|
||||
/// </summary>
|
||||
private readonly IApplicationPaths _appPaths;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
||||
/// <summary>
|
||||
/// The _save item command
|
||||
|
@ -81,35 +82,31 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
private IDbCommand _updateInheritedRatingCommand;
|
||||
private IDbCommand _updateInheritedTagsCommand;
|
||||
|
||||
private const int LatestSchemaVersion = 65;
|
||||
public const int LatestSchemaVersion = 68;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
|
||||
/// </summary>
|
||||
/// <param name="appPaths">The app paths.</param>
|
||||
/// <param name="jsonSerializer">The json serializer.</param>
|
||||
/// <param name="logManager">The log manager.</param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// appPaths
|
||||
/// or
|
||||
/// jsonSerializer
|
||||
/// </exception>
|
||||
public SqliteItemRepository(IApplicationPaths appPaths, IJsonSerializer jsonSerializer, ILogManager logManager)
|
||||
public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogManager logManager)
|
||||
: base(logManager)
|
||||
{
|
||||
if (appPaths == null)
|
||||
if (config == null)
|
||||
{
|
||||
throw new ArgumentNullException("appPaths");
|
||||
throw new ArgumentNullException("config");
|
||||
}
|
||||
if (jsonSerializer == null)
|
||||
{
|
||||
throw new ArgumentNullException("jsonSerializer");
|
||||
}
|
||||
|
||||
_appPaths = appPaths;
|
||||
_config = config;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
|
||||
_criticReviewsPath = Path.Combine(_appPaths.DataPath, "critic-reviews");
|
||||
_criticReviewsPath = Path.Combine(_config.ApplicationPaths.DataPath, "critic-reviews");
|
||||
}
|
||||
|
||||
private const string ChaptersTableName = "Chapters2";
|
||||
|
@ -118,11 +115,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
/// Opens the connection to the database
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
public async Task Initialize()
|
||||
public async Task Initialize(IDbConnector dbConnector)
|
||||
{
|
||||
var dbFile = Path.Combine(_appPaths.DataPath, "library.db");
|
||||
var dbFile = Path.Combine(_config.ApplicationPaths.DataPath, "library.db");
|
||||
|
||||
_connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
|
||||
_connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
|
||||
|
||||
var createMediaStreamsTableCommand
|
||||
= "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, CodecTag TEXT NULL, Comment TEXT NULL, NalLengthSize TEXT NULL, IsAvc BIT NULL, PRIMARY KEY (ItemId, StreamIndex))";
|
||||
|
@ -228,18 +225,27 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
_connection.AddColumn(Logger, "TypedBaseItems", "DateModifiedDuringLastRefresh", "DATETIME");
|
||||
_connection.AddColumn(Logger, "TypedBaseItems", "InheritedTags", "Text");
|
||||
_connection.AddColumn(Logger, "TypedBaseItems", "CleanName", "Text");
|
||||
_connection.AddColumn(Logger, "TypedBaseItems", "PresentationUniqueKey", "Text");
|
||||
|
||||
string[] postQueries =
|
||||
{
|
||||
"create index if not exists idx_PresentationUniqueKey on TypedBaseItems(PresentationUniqueKey)",
|
||||
"create index if not exists idx_Type on TypedBaseItems(Type)"
|
||||
};
|
||||
|
||||
_connection.RunQueries(postQueries, Logger);
|
||||
|
||||
PrepareStatements();
|
||||
|
||||
new MediaStreamColumns(_connection, Logger).AddColumns();
|
||||
|
||||
var chapterDbFile = Path.Combine(_appPaths.DataPath, "chapters.db");
|
||||
var chapterDbFile = Path.Combine(_config.ApplicationPaths.DataPath, "chapters.db");
|
||||
if (File.Exists(chapterDbFile))
|
||||
{
|
||||
MigrateChapters(chapterDbFile);
|
||||
}
|
||||
|
||||
var mediaStreamsDbFile = Path.Combine(_appPaths.DataPath, "mediainfo.db");
|
||||
var mediaStreamsDbFile = Path.Combine(_config.ApplicationPaths.DataPath, "mediainfo.db");
|
||||
if (File.Exists(mediaStreamsDbFile))
|
||||
{
|
||||
MigrateMediaStreams(mediaStreamsDbFile);
|
||||
|
@ -252,7 +258,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
{
|
||||
var backupFile = file + ".bak";
|
||||
File.Copy(file, backupFile, true);
|
||||
SqliteExtensions.Attach(_connection, backupFile, "MediaInfoOld");
|
||||
DataExtensions.Attach(_connection, backupFile, "MediaInfoOld");
|
||||
|
||||
var columns = string.Join(",", _mediaStreamSaveColumns);
|
||||
|
||||
|
@ -278,7 +284,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
{
|
||||
var backupFile = file + ".bak";
|
||||
File.Copy(file, backupFile, true);
|
||||
SqliteExtensions.Attach(_connection, backupFile, "ChaptersOld");
|
||||
DataExtensions.Attach(_connection, backupFile, "ChaptersOld");
|
||||
|
||||
string[] queries = {
|
||||
"REPLACE INTO "+ChaptersTableName+"(ItemId, ChapterIndex, StartPositionTicks, Name, ImagePath) SELECT ItemId, ChapterIndex, StartPositionTicks, Name, ImagePath FROM ChaptersOld.Chapters;"
|
||||
|
@ -469,7 +475,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
"CriticRatingSummary",
|
||||
"DateModifiedDuringLastRefresh",
|
||||
"InheritedTags",
|
||||
"CleanName"
|
||||
"CleanName",
|
||||
"PresentationUniqueKey"
|
||||
};
|
||||
_saveItemCommand = _connection.CreateCommand();
|
||||
_saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
|
||||
|
@ -803,6 +810,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
{
|
||||
_saveItemCommand.GetParameter(index++).Value = item.Name.RemoveDiacritics();
|
||||
}
|
||||
_saveItemCommand.GetParameter(index++).Value = item.PresentationUniqueKey;
|
||||
|
||||
_saveItemCommand.Transaction = transaction;
|
||||
|
||||
|
@ -1463,6 +1471,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
|
||||
CheckDisposed();
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
using (var cmd = _connection.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "select " + string.Join(",", _retriveItemColumns) + " from TypedBaseItems";
|
||||
|
@ -1475,6 +1485,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
|
||||
cmd.CommandText += whereText;
|
||||
|
||||
if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
|
||||
{
|
||||
cmd.CommandText += " Group by PresentationUniqueKey";
|
||||
}
|
||||
|
||||
cmd.CommandText += GetOrderByText(query);
|
||||
|
||||
if (query.Limit.HasValue)
|
||||
|
@ -1482,10 +1497,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
//Logger.Debug(cmd.CommandText);
|
||||
|
||||
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
|
||||
{
|
||||
Logger.Debug("GetItemList query time: {0}ms. Query: {1}",
|
||||
Convert.ToInt32((DateTime.UtcNow - now).TotalMilliseconds),
|
||||
cmd.CommandText);
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
var item = GetItem(reader);
|
||||
|
@ -1507,6 +1524,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
|
||||
CheckDisposed();
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
using (var cmd = _connection.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "select " + string.Join(",", _retriveItemColumns) + " from TypedBaseItems";
|
||||
|
@ -1525,6 +1544,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
|
||||
cmd.CommandText += whereText;
|
||||
|
||||
if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
|
||||
{
|
||||
cmd.CommandText += " Group by PresentationUniqueKey";
|
||||
}
|
||||
|
||||
cmd.CommandText += GetOrderByText(query);
|
||||
|
||||
if (query.Limit.HasValue)
|
||||
|
@ -1532,15 +1556,24 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging;
|
||||
|
||||
//Logger.Debug(cmd.CommandText);
|
||||
if (_config.Configuration.SchemaVersion >= 66)
|
||||
{
|
||||
cmd.CommandText += "; select count (distinct PresentationUniqueKey) from TypedBaseItems" + whereTextWithoutPaging;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging;
|
||||
}
|
||||
|
||||
var list = new List<BaseItem>();
|
||||
var count = 0;
|
||||
|
||||
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
|
||||
{
|
||||
Logger.Debug("GetItems query time: {0}ms. Query: {1}",
|
||||
Convert.ToInt32((DateTime.UtcNow - now).TotalMilliseconds),
|
||||
cmd.CommandText);
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
var item = GetItem(reader);
|
||||
|
@ -1608,6 +1641,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
|
||||
CheckDisposed();
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
using (var cmd = _connection.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "select guid from TypedBaseItems";
|
||||
|
@ -1620,6 +1655,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
|
||||
cmd.CommandText += whereText;
|
||||
|
||||
if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
|
||||
{
|
||||
cmd.CommandText += " Group by PresentationUniqueKey";
|
||||
}
|
||||
|
||||
cmd.CommandText += GetOrderByText(query);
|
||||
|
||||
if (query.Limit.HasValue)
|
||||
|
@ -1629,10 +1669,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
|
||||
var list = new List<Guid>();
|
||||
|
||||
//Logger.Debug(cmd.CommandText);
|
||||
|
||||
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
|
||||
{
|
||||
Logger.Debug("GetItemIdsList query time: {0}ms. Query: {1}",
|
||||
Convert.ToInt32((DateTime.UtcNow - now).TotalMilliseconds),
|
||||
cmd.CommandText);
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
list.Add(reader.GetGuid(0));
|
||||
|
@ -1662,7 +1704,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
string.Empty :
|
||||
" where " + string.Join(" AND ", whereClauses.ToArray());
|
||||
|
||||
whereClauses = GetWhereClauses(query, cmd, true);
|
||||
whereClauses = GetWhereClauses(query, cmd, true, false);
|
||||
|
||||
var whereText = whereClauses.Count == 0 ?
|
||||
string.Empty :
|
||||
|
@ -1670,6 +1712,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
|
||||
cmd.CommandText += whereText;
|
||||
|
||||
if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
|
||||
{
|
||||
cmd.CommandText += " Group by PresentationUniqueKey";
|
||||
}
|
||||
|
||||
cmd.CommandText += GetOrderByText(query);
|
||||
|
||||
if (query.Limit.HasValue)
|
||||
|
@ -1721,6 +1768,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
|
||||
CheckDisposed();
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
using (var cmd = _connection.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "select guid from TypedBaseItems";
|
||||
|
@ -1739,6 +1788,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
|
||||
cmd.CommandText += whereText;
|
||||
|
||||
if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
|
||||
{
|
||||
cmd.CommandText += " Group by PresentationUniqueKey";
|
||||
}
|
||||
|
||||
cmd.CommandText += GetOrderByText(query);
|
||||
|
||||
if (query.Limit.HasValue)
|
||||
|
@ -1746,15 +1800,24 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging;
|
||||
if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
|
||||
{
|
||||
cmd.CommandText += "; select count (distinct PresentationUniqueKey) from TypedBaseItems" + whereTextWithoutPaging;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.CommandText += "; select count (guid) from TypedBaseItems" + whereTextWithoutPaging;
|
||||
}
|
||||
|
||||
var list = new List<Guid>();
|
||||
var count = 0;
|
||||
|
||||
//Logger.Debug(cmd.CommandText);
|
||||
|
||||
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
|
||||
{
|
||||
Logger.Debug("GetItemIds query time: {0}ms. Query: {1}",
|
||||
Convert.ToInt32((DateTime.UtcNow - now).TotalMilliseconds),
|
||||
cmd.CommandText);
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
list.Add(reader.GetGuid(0));
|
||||
|
@ -1774,7 +1837,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
}
|
||||
}
|
||||
|
||||
private List<string> GetWhereClauses(InternalItemsQuery query, IDbCommand cmd, bool addPaging)
|
||||
private List<string> GetWhereClauses(InternalItemsQuery query, IDbCommand cmd, bool addPaging, bool enablePresentationUniqueKey = true)
|
||||
{
|
||||
var whereClauses = new List<string>();
|
||||
|
||||
|
@ -1873,6 +1936,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
cmd.Parameters.Add(cmd, "@Path", DbType.String).Value = query.Path;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(query.PresentationUniqueKey))
|
||||
{
|
||||
whereClauses.Add("PresentationUniqueKey=@PresentationUniqueKey");
|
||||
cmd.Parameters.Add(cmd, "@PresentationUniqueKey", DbType.String).Value = query.PresentationUniqueKey;
|
||||
}
|
||||
|
||||
if (query.MinCommunityRating.HasValue)
|
||||
{
|
||||
whereClauses.Add("CommunityRating>=@MinCommunityRating");
|
||||
|
@ -1998,9 +2067,40 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
|
||||
if (!string.IsNullOrWhiteSpace(query.NameContains))
|
||||
{
|
||||
whereClauses.Add("CleanName like @NameContains");
|
||||
if (_config.Configuration.SchemaVersion >= 66)
|
||||
{
|
||||
whereClauses.Add("CleanName like @NameContains");
|
||||
}
|
||||
else
|
||||
{
|
||||
whereClauses.Add("Name like @NameContains");
|
||||
}
|
||||
cmd.Parameters.Add(cmd, "@NameContains", DbType.String).Value = "%" + query.NameContains + "%";
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(query.NameStartsWith))
|
||||
{
|
||||
if (_config.Configuration.SchemaVersion >= 66)
|
||||
{
|
||||
whereClauses.Add("CleanName like @NameStartsWith");
|
||||
}
|
||||
else
|
||||
{
|
||||
whereClauses.Add("Name like @NameStartsWith");
|
||||
}
|
||||
cmd.Parameters.Add(cmd, "@NameStartsWith", DbType.String).Value = query.NameStartsWith + "%";
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(query.NameStartsWithOrGreater))
|
||||
{
|
||||
whereClauses.Add("SortName >= @NameStartsWithOrGreater");
|
||||
// lowercase this because SortName is stored as lowercase
|
||||
cmd.Parameters.Add(cmd, "@NameStartsWithOrGreater", DbType.String).Value = query.NameStartsWithOrGreater.ToLower();
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(query.NameLessThan))
|
||||
{
|
||||
whereClauses.Add("SortName < @NameLessThan");
|
||||
// lowercase this because SortName is stored as lowercase
|
||||
cmd.Parameters.Add(cmd, "@NameLessThan", DbType.String).Value = query.NameLessThan.ToLower();
|
||||
}
|
||||
|
||||
if (query.Genres.Length > 0)
|
||||
{
|
||||
|
@ -2134,7 +2234,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
whereClauses.Add("MediaType in (" + val + ")");
|
||||
}
|
||||
|
||||
var enableItemsByName = query.IncludeItemsByName ?? query.IncludeItemTypes.Length > 0;
|
||||
//var enableItemsByName = query.IncludeItemsByName ?? query.IncludeItemTypes.Length > 0;
|
||||
var enableItemsByName = query.IncludeItemsByName ?? false;
|
||||
|
||||
if (query.TopParentIds.Length == 1)
|
||||
{
|
||||
|
@ -2197,7 +2298,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
excludeTagIndex = 0;
|
||||
foreach (var excludeTag in query.ExcludeInheritedTags)
|
||||
{
|
||||
whereClauses.Add("(InheritedTags is null OR InheritedTags not like @excludeInheritedTag" + excludeTagIndex +")");
|
||||
whereClauses.Add("(InheritedTags is null OR InheritedTags not like @excludeInheritedTag" + excludeTagIndex + ")");
|
||||
cmd.Parameters.Add(cmd, "@excludeInheritedTag" + excludeTagIndex, DbType.String).Value = "%" + excludeTag + "%";
|
||||
excludeTagIndex++;
|
||||
}
|
||||
|
@ -2210,6 +2311,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
string.Empty :
|
||||
" where " + string.Join(" AND ", whereClauses.ToArray());
|
||||
|
||||
if (enablePresentationUniqueKey && EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66)
|
||||
{
|
||||
pagingWhereText += " Group by PresentationUniqueKey";
|
||||
}
|
||||
|
||||
var orderBy = GetOrderByText(query);
|
||||
|
||||
whereClauses.Add(string.Format("guid NOT IN (SELECT guid FROM TypedBaseItems {0}" + orderBy + " LIMIT {1})",
|
||||
|
@ -2221,6 +2327,34 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
return whereClauses;
|
||||
}
|
||||
|
||||
private bool EnableGroupByPresentationUniqueKey(InternalItemsQuery query)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(query.PresentationUniqueKey))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (query.IncludeItemTypes.Length == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var types = new[] {
|
||||
typeof(Episode).Name,
|
||||
typeof(Video).Name ,
|
||||
typeof(Movie).Name ,
|
||||
typeof(MusicVideo).Name ,
|
||||
typeof(Series).Name ,
|
||||
typeof(Season).Name };
|
||||
|
||||
if (types.Any(i => query.IncludeItemTypes.Contains(i, StringComparer.OrdinalIgnoreCase)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static readonly Type[] KnownTypes =
|
||||
{
|
||||
typeof(LiveTvProgram),
|
||||
|
@ -2299,7 +2433,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
try
|
||||
{
|
||||
transaction = _connection.BeginTransaction();
|
||||
|
||||
|
||||
foreach (var item in newValues)
|
||||
{
|
||||
_updateInheritedTagsCommand.GetParameter(0).Value = item.Item1;
|
||||
|
|
|
@ -39,11 +39,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
/// Opens the connection to the database
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
public async Task Initialize()
|
||||
public async Task Initialize(IDbConnector dbConnector)
|
||||
{
|
||||
var dbFile = Path.Combine(_appPaths.DataPath, "refreshinfo.db");
|
||||
|
||||
_connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
|
||||
_connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
|
||||
|
||||
string[] queries = {
|
||||
|
||||
|
|
|
@ -37,11 +37,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
/// Opens the connection to the database
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
public async Task Initialize()
|
||||
public async Task Initialize(IDbConnector dbConnector)
|
||||
{
|
||||
var dbFile = Path.Combine(_appPaths.DataPath, "userdata_v2.db");
|
||||
|
||||
_connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
|
||||
_connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
|
||||
|
||||
string[] queries = {
|
||||
|
||||
|
|
|
@ -43,12 +43,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
/// Opens the connection to the database
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
public async Task Initialize()
|
||||
public async Task Initialize(IDbConnector dbConnector)
|
||||
{
|
||||
var dbFile = Path.Combine(_appPaths.DataPath, "users.db");
|
||||
|
||||
_connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
|
||||
|
||||
_connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
|
||||
|
||||
string[] queries = {
|
||||
|
||||
"create table if not exists users (guid GUID primary key, data BLOB)",
|
||||
|
|
|
@ -27,11 +27,11 @@ namespace MediaBrowser.Server.Implementations.Security
|
|||
_appPaths = appPaths;
|
||||
}
|
||||
|
||||
public async Task Initialize()
|
||||
public async Task Initialize(IDbConnector dbConnector)
|
||||
{
|
||||
var dbFile = Path.Combine(_appPaths.DataPath, "authentication.db");
|
||||
|
||||
_connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
|
||||
_connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
|
||||
|
||||
string[] queries = {
|
||||
|
||||
|
|
|
@ -601,11 +601,9 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
|
||||
if (libraryItem != null)
|
||||
{
|
||||
var key = libraryItem.GetUserDataKey();
|
||||
|
||||
foreach (var user in users)
|
||||
{
|
||||
await OnPlaybackStart(user.Id, key, libraryItem).ConfigureAwait(false);
|
||||
await OnPlaybackStart(user.Id, libraryItem).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,12 +630,11 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
/// Called when [playback start].
|
||||
/// </summary>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <param name="userDataKey">The user data key.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>Task.</returns>
|
||||
private async Task OnPlaybackStart(Guid userId, string userDataKey, IHasUserData item)
|
||||
private async Task OnPlaybackStart(Guid userId, IHasUserData item)
|
||||
{
|
||||
var data = _userDataRepository.GetUserData(userId, userDataKey);
|
||||
var data = _userDataRepository.GetUserData(userId, item);
|
||||
|
||||
data.PlayCount++;
|
||||
data.LastPlayedDate = DateTime.UtcNow;
|
||||
|
@ -676,11 +673,9 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
|
||||
if (libraryItem != null)
|
||||
{
|
||||
var key = libraryItem.GetUserDataKey();
|
||||
|
||||
foreach (var user in users)
|
||||
{
|
||||
await OnPlaybackProgress(user, key, libraryItem, info).ConfigureAwait(false);
|
||||
await OnPlaybackProgress(user, libraryItem, info).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -714,9 +709,9 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
StartIdleCheckTimer();
|
||||
}
|
||||
|
||||
private async Task OnPlaybackProgress(User user, string userDataKey, BaseItem item, PlaybackProgressInfo info)
|
||||
private async Task OnPlaybackProgress(User user, BaseItem item, PlaybackProgressInfo info)
|
||||
{
|
||||
var data = _userDataRepository.GetUserData(user.Id, userDataKey);
|
||||
var data = _userDataRepository.GetUserData(user.Id, item);
|
||||
|
||||
var positionTicks = info.PositionTicks;
|
||||
|
||||
|
@ -811,11 +806,9 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
|
||||
if (libraryItem != null)
|
||||
{
|
||||
var key = libraryItem.GetUserDataKey();
|
||||
|
||||
foreach (var user in users)
|
||||
{
|
||||
playedToCompletion = await OnPlaybackStopped(user.Id, key, libraryItem, info.PositionTicks, info.Failed).ConfigureAwait(false);
|
||||
playedToCompletion = await OnPlaybackStopped(user.Id, libraryItem, info.PositionTicks, info.Failed).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -848,13 +841,13 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
await SendPlaybackStoppedNotification(session, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<bool> OnPlaybackStopped(Guid userId, string userDataKey, BaseItem item, long? positionTicks, bool playbackFailed)
|
||||
private async Task<bool> OnPlaybackStopped(Guid userId, BaseItem item, long? positionTicks, bool playbackFailed)
|
||||
{
|
||||
bool playedToCompletion = false;
|
||||
|
||||
if (!playbackFailed)
|
||||
{
|
||||
var data = _userDataRepository.GetUserData(userId, userDataKey);
|
||||
var data = _userDataRepository.GetUserData(userId, item);
|
||||
|
||||
if (positionTicks.HasValue)
|
||||
{
|
||||
|
|
|
@ -26,11 +26,11 @@ namespace MediaBrowser.Server.Implementations.Social
|
|||
/// Opens the connection to the database
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
public async Task Initialize()
|
||||
public async Task Initialize(IDbConnector dbConnector)
|
||||
{
|
||||
var dbFile = Path.Combine(_appPaths.DataPath, "shares.db");
|
||||
|
||||
_connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
|
||||
_connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
|
||||
|
||||
string[] queries = {
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ namespace MediaBrowser.Server.Implementations.Sorting
|
|||
|
||||
private int Compare(Episode x, Episode y)
|
||||
{
|
||||
var isXSpecial = (x.PhysicalSeasonNumber ?? -1) == 0;
|
||||
var isYSpecial = (y.PhysicalSeasonNumber ?? -1) == 0;
|
||||
var isXSpecial = (x.ParentIndexNumber ?? -1) == 0;
|
||||
var isYSpecial = (y.ParentIndexNumber ?? -1) == 0;
|
||||
|
||||
if (isXSpecial && isYSpecial)
|
||||
{
|
||||
|
@ -74,7 +74,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
|
|||
{
|
||||
// http://thetvdb.com/wiki/index.php?title=Special_Episodes
|
||||
|
||||
var xSeason = x.PhysicalSeasonNumber ?? -1;
|
||||
var xSeason = x.ParentIndexNumber ?? -1;
|
||||
var ySeason = y.AirsAfterSeasonNumber ?? y.AirsBeforeSeasonNumber ?? -1;
|
||||
|
||||
if (xSeason != ySeason)
|
||||
|
@ -142,8 +142,8 @@ namespace MediaBrowser.Server.Implementations.Sorting
|
|||
|
||||
private int CompareEpisodes(Episode x, Episode y)
|
||||
{
|
||||
var xValue = (x.PhysicalSeasonNumber ?? -1) * 1000 + (x.IndexNumber ?? -1);
|
||||
var yValue = (y.PhysicalSeasonNumber ?? -1) * 1000 + (y.IndexNumber ?? -1);
|
||||
var xValue = (x.ParentIndexNumber ?? -1) * 1000 + (x.IndexNumber ?? -1);
|
||||
var yValue = (y.ParentIndexNumber ?? -1) * 1000 + (y.IndexNumber ?? -1);
|
||||
|
||||
return xValue.CompareTo(yValue);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
|
|||
/// <returns>DateTime.</returns>
|
||||
private DateTime GetDate(BaseItem x)
|
||||
{
|
||||
var userdata = UserDataRepository.GetUserData(User.Id, x.GetUserDataKey());
|
||||
var userdata = UserDataRepository.GetUserData(User, x);
|
||||
|
||||
if (userdata != null && userdata.LastPlayedDate.HasValue)
|
||||
{
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
|
|||
/// <returns>DateTime.</returns>
|
||||
private int GetValue(BaseItem x)
|
||||
{
|
||||
var userdata = UserDataRepository.GetUserData(User.Id, x.GetUserDataKey());
|
||||
var userdata = UserDataRepository.GetUserData(User, x);
|
||||
|
||||
return userdata == null ? 0 : userdata.PlayCount;
|
||||
}
|
||||
|
|
|
@ -687,7 +687,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
|||
private Task ReportOfflinePlayedItem(UserAction action)
|
||||
{
|
||||
var item = _libraryManager.GetItemById(action.ItemId);
|
||||
var userData = _userDataManager.GetUserData(new Guid(action.UserId), item.GetUserDataKey());
|
||||
var userData = _userDataManager.GetUserData(action.UserId, item);
|
||||
|
||||
userData.LastPlayedDate = action.Date;
|
||||
_userDataManager.UpdatePlayState(item, userData, action.PositionTicks);
|
||||
|
|
|
@ -39,11 +39,11 @@ namespace MediaBrowser.Server.Implementations.Sync
|
|||
_appPaths = appPaths;
|
||||
}
|
||||
|
||||
public async Task Initialize()
|
||||
public async Task Initialize(IDbConnector dbConnector)
|
||||
{
|
||||
var dbFile = Path.Combine(_appPaths.DataPath, "sync14.db");
|
||||
|
||||
_connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
|
||||
_connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
|
||||
|
||||
string[] queries = {
|
||||
|
||||
|
|
|
@ -36,10 +36,25 @@ namespace MediaBrowser.Server.Implementations.TV
|
|||
? new string[] { }
|
||||
: new[] { request.ParentId };
|
||||
|
||||
string presentationUniqueKey = null;
|
||||
int? limit = null;
|
||||
if (!string.IsNullOrWhiteSpace(request.SeriesId))
|
||||
{
|
||||
var series = _libraryManager.GetItemById(request.SeriesId);
|
||||
|
||||
if (series != null)
|
||||
{
|
||||
presentationUniqueKey = series.PresentationUniqueKey;
|
||||
limit = 1;
|
||||
}
|
||||
}
|
||||
|
||||
var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
IncludeItemTypes = new[] { typeof(Series).Name },
|
||||
SortOrder = SortOrder.Ascending
|
||||
SortOrder = SortOrder.Ascending,
|
||||
PresentationUniqueKey = presentationUniqueKey,
|
||||
Limit = limit
|
||||
|
||||
}, parentIds).Cast<Series>();
|
||||
|
||||
|
@ -58,10 +73,25 @@ namespace MediaBrowser.Server.Implementations.TV
|
|||
throw new ArgumentException("User not found");
|
||||
}
|
||||
|
||||
string presentationUniqueKey = null;
|
||||
int? limit = null;
|
||||
if (!string.IsNullOrWhiteSpace(request.SeriesId))
|
||||
{
|
||||
var series = _libraryManager.GetItemById(request.SeriesId);
|
||||
|
||||
if (series != null)
|
||||
{
|
||||
presentationUniqueKey = series.PresentationUniqueKey;
|
||||
limit = 1;
|
||||
}
|
||||
}
|
||||
|
||||
var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
IncludeItemTypes = new[] { typeof(Series).Name },
|
||||
SortOrder = SortOrder.Ascending
|
||||
SortOrder = SortOrder.Ascending,
|
||||
PresentationUniqueKey = presentationUniqueKey,
|
||||
Limit = limit
|
||||
|
||||
}, parentsFolders.Select(i => i.Id.ToString("N"))).Cast<Series>();
|
||||
|
||||
|
@ -76,30 +106,30 @@ namespace MediaBrowser.Server.Implementations.TV
|
|||
// Avoid implicitly captured closure
|
||||
var currentUser = user;
|
||||
|
||||
return FilterSeries(request, series)
|
||||
return series
|
||||
.AsParallel()
|
||||
.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;
|
||||
//.OrderByDescending(i =>
|
||||
//{
|
||||
// var episode = i.Item1;
|
||||
|
||||
var seriesUserData = _userDataManager.GetUserData(user.Id, episode.Series.GetUserDataKey());
|
||||
// var seriesUserData = _userDataManager.GetUserData(user, episode.Series);
|
||||
|
||||
if (seriesUserData.IsFavorite)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
// if (seriesUserData.IsFavorite)
|
||||
// {
|
||||
// return 2;
|
||||
// }
|
||||
|
||||
if (seriesUserData.Likes.HasValue)
|
||||
{
|
||||
return seriesUserData.Likes.Value ? 1 : -1;
|
||||
}
|
||||
// if (seriesUserData.Likes.HasValue)
|
||||
// {
|
||||
// return seriesUserData.Likes.Value ? 1 : -1;
|
||||
// }
|
||||
|
||||
return 0;
|
||||
})
|
||||
.ThenByDescending(i => i.Item2)
|
||||
// return 0;
|
||||
//})
|
||||
.OrderByDescending(i => i.Item2)
|
||||
.ThenByDescending(i => i.Item1.PremiereDate ?? DateTime.MinValue)
|
||||
.Select(i => i.Item1);
|
||||
}
|
||||
|
@ -128,7 +158,7 @@ namespace MediaBrowser.Server.Implementations.TV
|
|||
// Go back starting with the most recent episodes
|
||||
foreach (var episode in allEpisodes)
|
||||
{
|
||||
var userData = _userDataManager.GetUserData(user.Id, episode.GetUserDataKey());
|
||||
var userData = _userDataManager.GetUserData(user, episode);
|
||||
|
||||
if (userData.Played)
|
||||
{
|
||||
|
@ -142,7 +172,7 @@ namespace MediaBrowser.Server.Implementations.TV
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!episode.IsVirtualUnaired && (!episode.IsMissingEpisode || includeMissing))
|
||||
if (!episode.IsVirtualUnaired && (includeMissing || !episode.IsMissingEpisode))
|
||||
{
|
||||
nextUp = episode;
|
||||
}
|
||||
|
@ -154,24 +184,12 @@ namespace MediaBrowser.Server.Implementations.TV
|
|||
return new Tuple<Episode, DateTime, bool>(nextUp, lastWatchedDate, false);
|
||||
}
|
||||
|
||||
var firstEpisode = allEpisodes.LastOrDefault(i => !i.IsVirtualUnaired && (!i.IsMissingEpisode || includeMissing) && !i.IsPlayed(user));
|
||||
var firstEpisode = allEpisodes.LastOrDefault(i => !i.IsVirtualUnaired && (includeMissing || !i.IsMissingEpisode) && !i.IsPlayed(user));
|
||||
|
||||
// Return the first episode
|
||||
return new Tuple<Episode, DateTime, bool>(firstEpisode, DateTime.MinValue, true);
|
||||
}
|
||||
|
||||
private IEnumerable<Series> FilterSeries(NextUpQuery request, IEnumerable<Series> items)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(request.SeriesId))
|
||||
{
|
||||
var id = new Guid(request.SeriesId);
|
||||
|
||||
items = items.Where(i => i.Id == id);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
private QueryResult<BaseItem> GetResult(IEnumerable<BaseItem> items, int? totalRecordLimit, NextUpQuery query)
|
||||
{
|
||||
var itemsArray = totalRecordLimit.HasValue ? items.Take(totalRecordLimit.Value).ToArray() : items.ToArray();
|
||||
|
|
|
@ -76,12 +76,17 @@
|
|||
<Reference Include="MediaBrowser.IsoMounting.Linux">
|
||||
<HintPath>..\ThirdParty\MediaBrowser.IsoMounting.Linux\MediaBrowser.IsoMounting.Linux.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Data.SQLite">
|
||||
<HintPath>..\ThirdParty\System.Data.SQLite.ManagedOnly\1.0.94.0\System.Data.SQLite.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\SharedVersion.cs">
|
||||
<Link>Properties\SharedVersion.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Native\BaseMonoApp.cs" />
|
||||
<Compile Include="Native\SqliteExtensions.cs" />
|
||||
<Compile Include="Networking\CertificateGenerator.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
|
|
@ -9,6 +9,7 @@ using System.Collections.Generic;
|
|||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using MediaBrowser.Controller.Power;
|
||||
using MediaBrowser.Server.Implementations.Persistence;
|
||||
using MediaBrowser.Server.Startup.Common.FFMpeg;
|
||||
using OperatingSystem = MediaBrowser.Server.Startup.Common.OperatingSystem;
|
||||
|
||||
|
@ -17,9 +18,12 @@ namespace MediaBrowser.Server.Mono.Native
|
|||
public abstract class BaseMonoApp : INativeApp
|
||||
{
|
||||
protected StartupOptions StartupOptions { get; private set; }
|
||||
protected BaseMonoApp(StartupOptions startupOptions)
|
||||
protected ILogger Logger { get; private set; }
|
||||
|
||||
protected BaseMonoApp(StartupOptions startupOptions, ILogger logger)
|
||||
{
|
||||
StartupOptions = startupOptions;
|
||||
Logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -227,6 +231,11 @@ namespace MediaBrowser.Server.Mono.Native
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IDbConnector GetDbConnector()
|
||||
{
|
||||
return new DbConnector(Logger);
|
||||
}
|
||||
|
||||
public static FFMpegInstallInfo GetInfo(NativeEnvironment environment)
|
||||
{
|
||||
var info = new FFMpegInstallInfo();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Server.Startup.Common;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Server.Startup.Common;
|
||||
|
||||
namespace MediaBrowser.Server.Mono.Native
|
||||
{
|
||||
|
@ -7,8 +8,8 @@ namespace MediaBrowser.Server.Mono.Native
|
|||
/// </summary>
|
||||
internal class NativeApp : BaseMonoApp
|
||||
{
|
||||
public NativeApp(StartupOptions startupOptions)
|
||||
: base(startupOptions)
|
||||
public NativeApp(StartupOptions startupOptions, ILogger logger)
|
||||
: base(startupOptions, logger)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
62
MediaBrowser.Server.Mono/Native/SqliteExtensions.cs
Normal file
62
MediaBrowser.Server.Mono/Native/SqliteExtensions.cs
Normal file
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using System.Data;
|
||||
using System.Data.SQLite;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Server.Implementations.Persistence;
|
||||
|
||||
namespace MediaBrowser.Server.Mono.Native
|
||||
{
|
||||
/// <summary>
|
||||
/// Class SQLiteExtensions
|
||||
/// </summary>
|
||||
static class SqliteExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Connects to db.
|
||||
/// </summary>
|
||||
/// <param name="dbPath">The db path.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <returns>Task{IDbConnection}.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">dbPath</exception>
|
||||
public static async Task<IDbConnection> ConnectToDb(string dbPath, ILogger logger)
|
||||
{
|
||||
if (string.IsNullOrEmpty(dbPath))
|
||||
{
|
||||
throw new ArgumentNullException("dbPath");
|
||||
}
|
||||
|
||||
logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath);
|
||||
|
||||
var connectionstr = new SQLiteConnectionStringBuilder
|
||||
{
|
||||
PageSize = 4096,
|
||||
CacheSize = 2000,
|
||||
SyncMode = SynchronizationModes.Full,
|
||||
DataSource = dbPath,
|
||||
JournalMode = SQLiteJournalModeEnum.Wal
|
||||
};
|
||||
|
||||
var connection = new SQLiteConnection(connectionstr.ConnectionString);
|
||||
|
||||
await connection.OpenAsync().ConfigureAwait(false);
|
||||
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
public class DbConnector : IDbConnector
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public DbConnector(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public Task<IDbConnection> Connect(string dbPath)
|
||||
{
|
||||
return SqliteExtensions.ConnectToDb(dbPath, _logger);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -79,7 +79,7 @@ namespace MediaBrowser.Server.Mono
|
|||
var fileSystem = new ManagedFileSystem(new PatternsLogger(logManager.GetLogger("FileSystem")), false, false);
|
||||
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
|
||||
|
||||
var nativeApp = new NativeApp(options);
|
||||
var nativeApp = new NativeApp(options, logManager.GetLogger("App"));
|
||||
|
||||
_appHost = new ApplicationHost(appPaths, logManager, options, fileSystem, "emby.mono.zip", nativeApp);
|
||||
|
||||
|
|
|
@ -410,13 +410,16 @@ namespace MediaBrowser.Server.Startup.Common
|
|||
UserRepository = await GetUserRepository().ConfigureAwait(false);
|
||||
RegisterSingleInstance(UserRepository);
|
||||
|
||||
DisplayPreferencesRepository = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths);
|
||||
var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths);
|
||||
DisplayPreferencesRepository = displayPreferencesRepo;
|
||||
RegisterSingleInstance(DisplayPreferencesRepository);
|
||||
|
||||
ItemRepository = new SqliteItemRepository(ApplicationPaths, JsonSerializer, LogManager);
|
||||
var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager);
|
||||
ItemRepository = itemRepo;
|
||||
RegisterSingleInstance(ItemRepository);
|
||||
|
||||
ProviderRepository = new SqliteProviderInfoRepository(LogManager, ApplicationPaths);
|
||||
var providerRepo = new SqliteProviderInfoRepository(LogManager, ApplicationPaths);
|
||||
ProviderRepository = providerRepo;
|
||||
RegisterSingleInstance(ProviderRepository);
|
||||
|
||||
FileOrganizationRepository = await GetFileOrganizationRepository().ConfigureAwait(false);
|
||||
|
@ -541,7 +544,7 @@ namespace MediaBrowser.Server.Startup.Common
|
|||
RegisterSingleInstance(NativeApp.GetPowerManagement());
|
||||
|
||||
var sharingRepo = new SharingRepository(LogManager, ApplicationPaths);
|
||||
await sharingRepo.Initialize().ConfigureAwait(false);
|
||||
await sharingRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false);
|
||||
RegisterSingleInstance<ISharingManager>(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this));
|
||||
|
||||
RegisterSingleInstance<ISsdpHandler>(new SsdpHandler(LogManager.GetLogger("SsdpHandler"), ServerConfigurationManager, this));
|
||||
|
@ -557,9 +560,11 @@ namespace MediaBrowser.Server.Startup.Common
|
|||
|
||||
SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager);
|
||||
RegisterSingleInstance(SubtitleEncoder);
|
||||
|
||||
await ConfigureDisplayPreferencesRepositories().ConfigureAwait(false);
|
||||
await ConfigureItemRepositories().ConfigureAwait(false);
|
||||
|
||||
await displayPreferencesRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false);
|
||||
await itemRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false);
|
||||
await providerRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false);
|
||||
((LibraryManager)LibraryManager).ItemRepository = ItemRepository;
|
||||
await ConfigureUserDataRepositories().ConfigureAwait(false);
|
||||
await ConfigureNotificationsRepository().ConfigureAwait(false);
|
||||
progress.Report(100);
|
||||
|
@ -658,7 +663,7 @@ namespace MediaBrowser.Server.Startup.Common
|
|||
{
|
||||
var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer);
|
||||
|
||||
await repo.Initialize().ConfigureAwait(false);
|
||||
await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false);
|
||||
|
||||
return repo;
|
||||
}
|
||||
|
@ -677,7 +682,7 @@ namespace MediaBrowser.Server.Startup.Common
|
|||
{
|
||||
var repo = new SqliteFileOrganizationRepository(LogManager, ServerConfigurationManager.ApplicationPaths);
|
||||
|
||||
await repo.Initialize().ConfigureAwait(false);
|
||||
await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false);
|
||||
|
||||
return repo;
|
||||
}
|
||||
|
@ -686,7 +691,7 @@ namespace MediaBrowser.Server.Startup.Common
|
|||
{
|
||||
var repo = new AuthenticationRepository(LogManager, ServerConfigurationManager.ApplicationPaths);
|
||||
|
||||
await repo.Initialize().ConfigureAwait(false);
|
||||
await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false);
|
||||
|
||||
return repo;
|
||||
}
|
||||
|
@ -695,7 +700,7 @@ namespace MediaBrowser.Server.Startup.Common
|
|||
{
|
||||
var repo = new ActivityRepository(LogManager, ServerConfigurationManager.ApplicationPaths);
|
||||
|
||||
await repo.Initialize().ConfigureAwait(false);
|
||||
await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false);
|
||||
|
||||
return repo;
|
||||
}
|
||||
|
@ -704,7 +709,7 @@ namespace MediaBrowser.Server.Startup.Common
|
|||
{
|
||||
var repo = new SyncRepository(LogManager, JsonSerializer, ServerConfigurationManager.ApplicationPaths);
|
||||
|
||||
await repo.Initialize().ConfigureAwait(false);
|
||||
await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false);
|
||||
|
||||
return repo;
|
||||
}
|
||||
|
@ -717,35 +722,13 @@ namespace MediaBrowser.Server.Startup.Common
|
|||
{
|
||||
var repo = new SqliteNotificationsRepository(LogManager, ApplicationPaths);
|
||||
|
||||
await repo.Initialize().ConfigureAwait(false);
|
||||
await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false);
|
||||
|
||||
NotificationsRepository = repo;
|
||||
|
||||
RegisterSingleInstance(NotificationsRepository);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the repositories.
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
private async Task ConfigureDisplayPreferencesRepositories()
|
||||
{
|
||||
await DisplayPreferencesRepository.Initialize().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the item repositories.
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
private async Task ConfigureItemRepositories()
|
||||
{
|
||||
await ItemRepository.Initialize().ConfigureAwait(false);
|
||||
|
||||
await ProviderRepository.Initialize().ConfigureAwait(false);
|
||||
|
||||
((LibraryManager)LibraryManager).ItemRepository = ItemRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the user data repositories.
|
||||
/// </summary>
|
||||
|
@ -754,7 +737,7 @@ namespace MediaBrowser.Server.Startup.Common
|
|||
{
|
||||
var repo = new SqliteUserDataRepository(LogManager, ApplicationPaths);
|
||||
|
||||
await repo.Initialize().ConfigureAwait(false);
|
||||
await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false);
|
||||
|
||||
((UserDataManager)UserDataManager).Repository = repo;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ using MediaBrowser.Model.Logging;
|
|||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using MediaBrowser.Controller.Power;
|
||||
using MediaBrowser.Server.Implementations.Persistence;
|
||||
using MediaBrowser.Server.Startup.Common.FFMpeg;
|
||||
|
||||
namespace MediaBrowser.Server.Startup.Common
|
||||
|
@ -104,5 +105,7 @@ namespace MediaBrowser.Server.Startup.Common
|
|||
FFMpegInstallInfo GetFfmpegInstallInfo();
|
||||
|
||||
void LaunchUrl(string url);
|
||||
|
||||
IDbConnector GetDbConnector();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
<FileAlignment>512</FileAlignment>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||
<TargetFrameworkProfile />
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
|
@ -81,9 +83,9 @@
|
|||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.SQLite, Version=1.0.94.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\System.Data.SQLite.Core.1.0.94.0\lib\net45\System.Data.SQLite.dll</HintPath>
|
||||
<Reference Include="System.Data.SQLite, Version=1.0.101.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Data.SQLite.Core.1.0.101.0\lib\net46\System.Data.SQLite.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
|
@ -112,6 +114,7 @@
|
|||
</Compile>
|
||||
<Compile Include="MainStartup.cs" />
|
||||
<Compile Include="Native\LnkShortcutHandler.cs" />
|
||||
<Compile Include="Native\SqliteExtensions.cs" />
|
||||
<Compile Include="Native\Standby.cs" />
|
||||
<Compile Include="Native\ServerAuthorization.cs" />
|
||||
<Compile Include="Native\WindowsApp.cs" />
|
||||
|
@ -156,14 +159,6 @@
|
|||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="..\packages\System.Data.SQLite.Core.1.0.94.0\build\net45\x64\SQLite.Interop.dll">
|
||||
<Link>x64\SQLite.Interop.dll</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\packages\System.Data.SQLite.Core.1.0.94.0\build\net45\x86\SQLite.Interop.dll">
|
||||
<Link>x86\SQLite.Interop.dll</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\Tools\Installation\MediaBrowser.InstallUtil.dll">
|
||||
<Link>MediaBrowser.InstallUtil.dll</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
|
@ -1116,6 +1111,13 @@
|
|||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\packages\System.Data.SQLite.Core.1.0.101.0\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.101.0\build\net46\System.Data.SQLite.Core.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\System.Data.SQLite.Core.1.0.101.0\build\net46\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\System.Data.SQLite.Core.1.0.101.0\build\net46\System.Data.SQLite.Core.targets'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
@ -1123,5 +1125,4 @@
|
|||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<Import Project="..\packages\System.Data.SQLite.Core.1.0.94.0\build\net45\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.94.0\build\net45\System.Data.SQLite.Core.targets')" />
|
||||
</Project>
|
62
MediaBrowser.ServerApplication/Native/SqliteExtensions.cs
Normal file
62
MediaBrowser.ServerApplication/Native/SqliteExtensions.cs
Normal file
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using System.Data;
|
||||
using System.Data.SQLite;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Server.Implementations.Persistence;
|
||||
|
||||
namespace MediaBrowser.ServerApplication.Native
|
||||
{
|
||||
/// <summary>
|
||||
/// Class SQLiteExtensions
|
||||
/// </summary>
|
||||
static class SqliteExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Connects to db.
|
||||
/// </summary>
|
||||
/// <param name="dbPath">The db path.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <returns>Task{IDbConnection}.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">dbPath</exception>
|
||||
public static async Task<IDbConnection> ConnectToDb(string dbPath, ILogger logger)
|
||||
{
|
||||
if (string.IsNullOrEmpty(dbPath))
|
||||
{
|
||||
throw new ArgumentNullException("dbPath");
|
||||
}
|
||||
|
||||
logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath);
|
||||
|
||||
var connectionstr = new SQLiteConnectionStringBuilder
|
||||
{
|
||||
PageSize = 4096,
|
||||
CacheSize = 2000,
|
||||
SyncMode = SynchronizationModes.Full,
|
||||
DataSource = dbPath,
|
||||
JournalMode = SQLiteJournalModeEnum.Wal
|
||||
};
|
||||
|
||||
var connection = new SQLiteConnection(connectionstr.ConnectionString);
|
||||
|
||||
await connection.OpenAsync().ConfigureAwait(false);
|
||||
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
public class DbConnector : IDbConnector
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public DbConnector(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public Task<IDbConnection> Connect(string dbPath)
|
||||
{
|
||||
return SqliteExtensions.ConnectToDb(dbPath, _logger);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ using System.Reflection;
|
|||
using System.Windows.Forms;
|
||||
using CommonIO;
|
||||
using MediaBrowser.Controller.Power;
|
||||
using MediaBrowser.Server.Implementations.Persistence;
|
||||
using MediaBrowser.Server.Startup.Common.FFMpeg;
|
||||
using OperatingSystem = MediaBrowser.Server.Startup.Common.OperatingSystem;
|
||||
|
||||
|
@ -191,6 +192,11 @@ namespace MediaBrowser.ServerApplication.Native
|
|||
}
|
||||
}
|
||||
|
||||
public IDbConnector GetDbConnector()
|
||||
{
|
||||
return new DbConnector(_logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes the exited.
|
||||
/// </summary>
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
<package id="CommonIO" version="1.0.0.9" targetFramework="net45" />
|
||||
<package id="ImageMagickSharp" version="1.0.0.18" targetFramework="net45" />
|
||||
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||
<package id="System.Data.SQLite.Core" version="1.0.94.0" targetFramework="net45" requireReinstallation="true" />
|
||||
<package id="System.Data.SQLite.Core" version="1.0.101.0" targetFramework="net46" />
|
||||
</packages>
|
|
@ -936,7 +936,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
|
|||
return;
|
||||
}
|
||||
|
||||
var userdata = userDataRepo.GetUserData(user.Id, item.GetUserDataKey());
|
||||
var userdata = userDataRepo.GetUserData(user, item);
|
||||
|
||||
writer.WriteElementString("isuserfavorite", userdata.IsFavorite.ToString().ToLower());
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System.Reflection;
|
||||
|
||||
//[assembly: AssemblyVersion("3.0.*")]
|
||||
[assembly: AssemblyVersion("3.0.5947")]
|
||||
[assembly: AssemblyVersion("3.0.*")]
|
||||
//[assembly: AssemblyVersion("3.0.5930")]
|
||||
|
|
Loading…
Reference in New Issue
Block a user