aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller/Entities')
-rw-r--r--MediaBrowser.Controller/Entities/Audio/Audio.cs34
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs32
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicArtist.cs19
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicGenre.cs11
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs47
-rw-r--r--MediaBrowser.Controller/Entities/CollectionFolder.cs27
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs31
-rw-r--r--MediaBrowser.Controller/Entities/Game.cs7
-rw-r--r--MediaBrowser.Controller/Entities/GameGenre.cs11
-rw-r--r--MediaBrowser.Controller/Entities/GameSystem.cs13
-rw-r--r--MediaBrowser.Controller/Entities/Genre.cs11
-rw-r--r--MediaBrowser.Controller/Entities/IHasUserData.cs7
-rw-r--r--MediaBrowser.Controller/Entities/InternalItemsQuery.cs1
-rw-r--r--MediaBrowser.Controller/Entities/Movies/Movie.cs30
-rw-r--r--MediaBrowser.Controller/Entities/MusicVideo.cs9
-rw-r--r--MediaBrowser.Controller/Entities/Person.cs11
-rw-r--r--MediaBrowser.Controller/Entities/Studio.cs11
-rw-r--r--MediaBrowser.Controller/Entities/TV/Episode.cs49
-rw-r--r--MediaBrowser.Controller/Entities/TV/Season.cs42
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs113
-rw-r--r--MediaBrowser.Controller/Entities/Trailer.cs22
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs10
-rw-r--r--MediaBrowser.Controller/Entities/Video.cs131
-rw-r--r--MediaBrowser.Controller/Entities/Year.cs11
24 files changed, 392 insertions, 298 deletions
diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs
index 929308ba08..fd56a6746a 100644
--- a/MediaBrowser.Controller/Entities/Audio/Audio.cs
+++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs
@@ -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()
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
index e6178c183b..5cb4e8c9d1 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
@@ -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);
+ var list = base.GetUserDataKeys();
- if (!string.IsNullOrWhiteSpace(id))
+ if (ConfigurationManager.Configuration.EnableStandaloneMusicKeys)
{
- return "MusicAlbum-MusicBrainzReleaseGroup-" + id;
+ var albumArtist = AlbumArtist;
+ if (!string.IsNullOrWhiteSpace(albumArtist))
+ {
+ list.Insert(0, albumArtist + "-" + Name);
+ }
}
- id = this.GetProviderId(MetadataProviders.MusicBrainzAlbum);
+ var id = this.GetProviderId(MetadataProviders.MusicBrainzAlbum);
if (!string.IsNullOrWhiteSpace(id))
{
- return "MusicAlbum-Musicbrainz-" + id;
+ list.Insert(0, "MusicAlbum-Musicbrainz-" + id);
}
- if (ConfigurationManager.Configuration.EnableStandaloneMusicKeys)
+ id = this.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
+
+ if (!string.IsNullOrWhiteSpace(id))
{
- var albumArtist = AlbumArtist;
- if (!string.IsNullOrWhiteSpace(albumArtist))
- {
- return albumArtist + "-" + Name;
- }
+ list.Insert(0, "MusicAlbum-MusicBrainzReleaseGroup-" + id);
}
- return base.CreateUserDataKey();
+ return list;
}
protected override bool GetBlockUnratedValue(UserPolicy config)
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
index 02bcceada4..2cca632179 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
@@ -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)
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
index 45304d47ee..4d041264c0 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
@@ -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]
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 475e2ace83..6bf55e108c 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -125,6 +125,8 @@ namespace MediaBrowser.Controller.Entities
}
}
+ public string OriginalTitle { get; set; }
+
/// <summary>
/// Gets or sets the id.
/// </summary>
@@ -1147,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.
@@ -1156,7 +1164,7 @@ namespace MediaBrowser.Controller.Entities
{
if (string.IsNullOrWhiteSpace(_userDataKey))
{
- var key = CreateUserDataKey();
+ var key = GetUserDataKeys().First();
_userDataKey = key;
return key;
}
@@ -1164,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)
@@ -1540,11 +1552,11 @@ namespace MediaBrowser.Controller.Entities
{
if (!string.IsNullOrEmpty(info.Path))
{
- var itemByPath = LibraryManager.FindByPath(info.Path);
+ var itemByPath = LibraryManager.FindByPath(info.Path, null);
if (itemByPath == null)
{
- Logger.Warn("Unable to find linked item at path {0}", info.Path);
+ //Logger.Warn("Unable to find linked item at path {0}", info.Path);
}
return itemByPath;
@@ -1553,6 +1565,15 @@ namespace MediaBrowser.Controller.Entities
return null;
}
+ [IgnoreDataMember]
+ public virtual bool EnableRememberingTrackSelections
+ {
+ get
+ {
+ return true;
+ }
+ }
+
/// <summary>
/// Adds a studio to the item
/// </summary>
@@ -1606,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)
{
@@ -1643,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
@@ -1976,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));
}
@@ -1995,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;
}
diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs
index 4297003277..5e0cf6e88b 100644
--- a/MediaBrowser.Controller/Entities/CollectionFolder.cs
+++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs
@@ -8,6 +8,7 @@ using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MoreLinq;
namespace MediaBrowser.Controller.Entities
{
@@ -97,7 +98,6 @@ namespace MediaBrowser.Controller.Entities
}
}
-
return base.IsValidFromResolver(newItem);
}
@@ -200,9 +200,30 @@ namespace MediaBrowser.Controller.Entities
public IEnumerable<Folder> GetPhysicalParents()
{
- return LibraryManager.RootFolder.Children
+ var rootChildren = LibraryManager.RootFolder.Children
.OfType<Folder>()
- .Where(i => i.Path != null && PhysicalLocations.Contains(i.Path, StringComparer.OrdinalIgnoreCase));
+ .ToList();
+
+ return PhysicalLocations.Where(i => !string.Equals(i, Path, StringComparison.OrdinalIgnoreCase)).SelectMany(i => GetPhysicalParents(i, rootChildren)).DistinctBy(i => i.Id);
+ }
+
+ private IEnumerable<Folder> GetPhysicalParents(string path, List<Folder> rootChildren)
+ {
+ var result = rootChildren
+ .Where(i => string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase))
+ .ToList();
+
+ if (result.Count == 0)
+ {
+ var folder = LibraryManager.FindByPath(path, true) as Folder;
+
+ if (folder != null)
+ {
+ result.Add(folder);
+ }
+ }
+
+ return result;
}
[IgnoreDataMember]
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index f4cdc8fa1b..fca2c6e439 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -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)
diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs
index e597b2a152..9ed2400469 100644
--- a/MediaBrowser.Controller/Entities/Game.cs
+++ b/MediaBrowser.Controller/Entities/Game.cs
@@ -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()
diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs
index d2b6b48568..71028d4cf7 100644
--- a/MediaBrowser.Controller/Entities/GameGenre.cs
+++ b/MediaBrowser.Controller/Entities/GameGenre.cs
@@ -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>
diff --git a/MediaBrowser.Controller/Entities/GameSystem.cs b/MediaBrowser.Controller/Entities/GameSystem.cs
index bc35c4738a..1c09ee5075 100644
--- a/MediaBrowser.Controller/Entities/GameSystem.cs
+++ b/MediaBrowser.Controller/Entities/GameSystem.cs
@@ -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)
diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs
index 233e1e0fd1..fa890ad9eb 100644
--- a/MediaBrowser.Controller/Entities/Genre.cs
+++ b/MediaBrowser.Controller/Entities/Genre.cs
@@ -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>
diff --git a/MediaBrowser.Controller/Entities/IHasUserData.cs b/MediaBrowser.Controller/Entities/IHasUserData.cs
index 34a8208533..3e0fa3f1dc 100644
--- a/MediaBrowser.Controller/Entities/IHasUserData.cs
+++ b/MediaBrowser.Controller/Entities/IHasUserData.cs
@@ -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>
@@ -20,5 +23,7 @@ namespace MediaBrowser.Controller.Entities
/// <param name="userData">The user data.</param>
/// <param name="user">The user.</param>
void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user);
+
+ bool EnableRememberingTrackSelections { get; }
}
}
diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
index f3b4f40534..b148251ff1 100644
--- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
+++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
@@ -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; }
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index 4d2ca9ffea..5882b5f4dd 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -18,8 +18,6 @@ namespace MediaBrowser.Controller.Entities.Movies
{
public List<Guid> SpecialFeatureIds { get; set; }
- public string OriginalTitle { get; set; }
-
public List<Guid> ThemeSongIds { get; set; }
public List<Guid> ThemeVideoIds { get; set; }
public List<string> ProductionLocations { get; set; }
@@ -77,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)
{
diff --git a/MediaBrowser.Controller/Entities/MusicVideo.cs b/MediaBrowser.Controller/Entities/MusicVideo.cs
index b52f16a462..bf4c2559c5 100644
--- a/MediaBrowser.Controller/Entities/MusicVideo.cs
+++ b/MediaBrowser.Controller/Entities/MusicVideo.cs
@@ -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;
diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs
index 560ea6e05e..89581e967d 100644
--- a/MediaBrowser.Controller/Entities/Person.cs
+++ b/MediaBrowser.Controller/Entities/Person.cs
@@ -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()
diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs
index a55527f37b..7ceefbc6e7 100644
--- a/MediaBrowser.Controller/Entities/Studio.cs
+++ b/MediaBrowser.Controller/Entities/Studio.cs
@@ -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>
diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs
index e1a91086b2..605b838cd7 100644
--- a/MediaBrowser.Controller/Entities/TV/Episode.cs
+++ b/MediaBrowser.Controller/Entities/TV/Episode.cs
@@ -58,60 +58,48 @@ namespace MediaBrowser.Controller.Entities.TV
{
get
{
- return AirsAfterSeasonNumber ?? AirsBeforeSeasonNumber ?? PhysicalSeasonNumber;
+ return AirsAfterSeasonNumber ?? AirsBeforeSeasonNumber ?? ParentIndexNumber;
}
}
[IgnoreDataMember]
- public int? PhysicalSeasonNumber
+ public override Folder LatestItemsIndexContainer
{
get
{
- var value = ParentIndexNumber;
-
- if (value.HasValue)
- {
- return value;
- }
-
- var season = Season;
-
- return season != null ? season.IndexNumber : null;
+ return Series;
}
}
[IgnoreDataMember]
- public override Folder LatestItemsIndexContainer
+ public override Guid? DisplayParentId
{
get
{
- return Series;
+ return SeasonId;
}
}
[IgnoreDataMember]
- public override Guid? DisplayParentId
+ protected override bool EnableDefaultVideoUserDataKeys
{
get
{
- return SeasonId;
+ return false;
}
}
- /// <summary>
- /// Gets the user data key.
- /// </summary>
- /// <returns>System.String.</returns>
- protected override string CreateUserDataKey()
+ public override List<string> GetUserDataKeys()
{
- var series = Series;
+ 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;
}
}
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index acd02e8ab9..1f443071c7 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -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;
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 9eeb89a1fa..abca6a6431 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -19,8 +19,6 @@ namespace MediaBrowser.Controller.Entities.TV
{
public List<Guid> SpecialFeatureIds { get; set; }
- public string OriginalTitle { get; set; }
-
public int? AnimeSeriesIndex { get; set; }
public Series()
@@ -93,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>
@@ -128,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"},
@@ -185,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)
{
@@ -204,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)
@@ -257,7 +281,7 @@ namespace MediaBrowser.Controller.Entities.TV
// Refresh current item
await RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
- // Refresh TV
+ // Refresh seasons
foreach (var item in seasons)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -270,12 +294,30 @@ namespace MediaBrowser.Controller.Entities.TV
progress.Report(percent * 100);
}
- // Refresh all non-songs
+ // Refresh episodes and other children
foreach (var item in otherItems)
{
cancellationToken.ThrowIfCancellationRequested();
- await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+ var skipItem = false;
+
+ var episode = item as Episode;
+
+ if (episode != null
+ && refreshOptions.MetadataRefreshMode != MetadataRefreshMode.FullRefresh
+ && !refreshOptions.ReplaceAllMetadata
+ && episode.IsMissingEpisode
+ && episode.LocationType == Model.Entities.LocationType.Virtual
+ && episode.PremiereDate.HasValue
+ && (DateTime.UtcNow - episode.PremiereDate.Value).TotalDays > 30)
+ {
+ skipItem = true;
+ }
+
+ if (!skipItem)
+ {
+ await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+ }
numComplete++;
double percent = numComplete;
@@ -297,18 +339,31 @@ 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;
- episodes = FilterEpisodesBySeason(episodes, seasonNumber, DisplaySpecialsWithSeasons);
+ 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 }
- episodes = episodes.Concat(additionalEpisodes).Distinct();
+ }).OfType<Episode>();
+ }
+ else
+ {
+ episodes = GetRecursiveChildren(user, i => i is Episode)
+ .Cast<Episode>();
+ }
+
+ episodes = FilterEpisodesBySeason(episodes, seasonNumber, DisplaySpecialsWithSeasons);
if (!includeMissingEpisodes)
{
@@ -336,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 =>
diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs
index c3e24090c3..3be2fc6243 100644
--- a/MediaBrowser.Controller/Entities/Trailer.cs
+++ b/MediaBrowser.Controller/Entities/Trailer.cs
@@ -11,7 +11,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Class Trailer
/// </summary>
- public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTaglines, IHasMetascore, IHasLookupInfo<TrailerInfo>
+ public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTaglines, IHasMetascore, IHasOriginalTitle, IHasLookupInfo<TrailerInfo>
{
public List<string> ProductionLocations { get; set; }
@@ -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;
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index db669ca37d..5a0e0b614b 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -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)
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index 2c7d3856b3..67b710534c 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -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;
+ }
+ }
+
+ public override List<string> GetUserDataKeys()
+ {
+ var list = base.GetUserDataKeys();
- if (!string.IsNullOrWhiteSpace(key))
+ if (EnableDefaultVideoUserDataKeys)
+ {
+ if (ExtraType.HasValue)
{
- key = key + "-" + ExtraType.ToString().ToLower();
+ var key = this.GetProviderId(MetadataProviders.Tmdb);
+ if (!string.IsNullOrWhiteSpace(key))
+ {
+ list.Insert(0, GetUserDataKey(key));
+ }
- // Make sure different trailers have their own data.
- if (RunTimeTicks.HasValue)
+ key = this.GetProviderId(MetadataProviders.Imdb);
+ if (!string.IsNullOrWhiteSpace(key))
{
- key += "-" + RunTimeTicks.Value.ToString(CultureInfo.InvariantCulture);
+ list.Insert(0, GetUserDataKey(key));
+ }
+ }
+ else
+ {
+ var key = this.GetProviderId(MetadataProviders.Imdb);
+ if (!string.IsNullOrWhiteSpace(key))
+ {
+ list.Insert(0, key);
}
- return 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()
@@ -317,6 +362,11 @@ namespace MediaBrowser.Controller.Entities
{
return false;
}
+
+ if (newAsVideo.VideoType != VideoType)
+ {
+ return false;
+ }
}
return base.IsValidFromResolver(newItem);
@@ -463,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)
@@ -481,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 =>
{
diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs
index 163dcd667c..f27ce79dd3 100644
--- a/MediaBrowser.Controller/Entities/Year.cs
+++ b/MediaBrowser.Controller/Entities/Year.cs
@@ -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>