update season queries
This commit is contained in:
parent
d6dc6ffe7e
commit
cc62faa1c2
|
@ -423,23 +423,14 @@ namespace MediaBrowser.Api
|
|||
throw new ResourceNotFoundException("No series exists with Id " + request.Id);
|
||||
}
|
||||
|
||||
var seasons = series.GetSeasons(user);
|
||||
|
||||
if (request.IsSpecialSeason.HasValue)
|
||||
var seasons = (await series.GetItems(new InternalItemsQuery(user)
|
||||
{
|
||||
var val = request.IsSpecialSeason.Value;
|
||||
IsMissing = request.IsMissing,
|
||||
IsVirtualUnaired = request.IsVirtualUnaired,
|
||||
IsSpecialSeason = request.IsSpecialSeason,
|
||||
AdjacentTo = request.AdjacentTo
|
||||
|
||||
seasons = seasons.Where(i => i.IsSpecialSeason == val);
|
||||
}
|
||||
|
||||
seasons = FilterVirtualSeasons(request, seasons);
|
||||
|
||||
// This must be the last filter
|
||||
if (!string.IsNullOrEmpty(request.AdjacentTo))
|
||||
{
|
||||
seasons = UserViewBuilder.FilterForAdjacency(seasons, request.AdjacentTo)
|
||||
.Cast<Season>();
|
||||
}
|
||||
}).ConfigureAwait(false)).Items.OfType<Season>();
|
||||
|
||||
var dtoOptions = GetDtoOptions(request);
|
||||
|
||||
|
@ -453,23 +444,6 @@ namespace MediaBrowser.Api
|
|||
};
|
||||
}
|
||||
|
||||
private IEnumerable<Season> FilterVirtualSeasons(GetSeasons request, IEnumerable<Season> items)
|
||||
{
|
||||
if (request.IsMissing.HasValue)
|
||||
{
|
||||
var val = request.IsMissing.Value;
|
||||
items = items.Where(i => (i.IsMissingSeason) == val);
|
||||
}
|
||||
|
||||
if (request.IsVirtualUnaired.HasValue)
|
||||
{
|
||||
var val = request.IsVirtualUnaired.Value;
|
||||
items = items.Where(i => i.IsVirtualUnaired == val);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public async Task<object> Get(GetEpisodes request)
|
||||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
|
|
@ -270,5 +270,54 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName = true)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validName = normalizeName ?
|
||||
FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
|
||||
name;
|
||||
|
||||
return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.ArtistsPath, validName);
|
||||
}
|
||||
|
||||
private string GetRebasedPath()
|
||||
{
|
||||
return GetPath(System.IO.Path.GetFileName(Path), false);
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Path = newPath;
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,5 +92,48 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
|
||||
return LibraryManager.GetItemList(query);
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName = true)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validName = normalizeName ?
|
||||
FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
|
||||
name;
|
||||
|
||||
return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.MusicGenrePath, validName);
|
||||
}
|
||||
|
||||
private string GetRebasedPath()
|
||||
{
|
||||
return GetPath(System.IO.Path.GetFileName(Path), false);
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Path = newPath;
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,5 +84,48 @@ namespace MediaBrowser.Controller.Entities
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName = true)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validName = normalizeName ?
|
||||
FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
|
||||
name;
|
||||
|
||||
return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.GameGenrePath, validName);
|
||||
}
|
||||
|
||||
private string GetRebasedPath()
|
||||
{
|
||||
return GetPath(System.IO.Path.GetFileName(Path), false);
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Path = newPath;
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,5 +87,48 @@ namespace MediaBrowser.Controller.Entities
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName = true)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validName = normalizeName ?
|
||||
FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
|
||||
name;
|
||||
|
||||
return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.GenrePath, validName);
|
||||
}
|
||||
|
||||
private string GetRebasedPath()
|
||||
{
|
||||
return GetPath(System.IO.Path.GetFileName(Path), false);
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Path = newPath;
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
public string[] Genres { get; set; }
|
||||
public string[] Keywords { get; set; }
|
||||
|
||||
public bool? IsSpecialSeason { get; set; }
|
||||
public bool? IsMissing { get; set; }
|
||||
public bool? IsUnaired { get; set; }
|
||||
public bool? IsVirtualUnaired { get; set; }
|
||||
|
@ -50,6 +51,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
public string PresentationUniqueKey { get; set; }
|
||||
public string Path { get; set; }
|
||||
public string PathNotStartsWith { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string SlugName { get; set; }
|
||||
|
||||
|
|
|
@ -122,6 +122,64 @@ namespace MediaBrowser.Controller.Entities
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName = true)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validFilename = normalizeName ?
|
||||
FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
|
||||
name;
|
||||
|
||||
string subFolderPrefix = null;
|
||||
|
||||
foreach (char c in validFilename)
|
||||
{
|
||||
if (char.IsLetterOrDigit(c))
|
||||
{
|
||||
subFolderPrefix = c.ToString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var path = ConfigurationManager.ApplicationPaths.PeoplePath;
|
||||
|
||||
return string.IsNullOrEmpty(subFolderPrefix) ?
|
||||
System.IO.Path.Combine(path, validFilename) :
|
||||
System.IO.Path.Combine(path, subFolderPrefix, validFilename);
|
||||
}
|
||||
|
||||
private string GetRebasedPath()
|
||||
{
|
||||
return GetPath(System.IO.Path.GetFileName(Path), false);
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Path = newPath;
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -85,5 +85,48 @@ namespace MediaBrowser.Controller.Entities
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName = true)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validName = normalizeName ?
|
||||
FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
|
||||
name;
|
||||
|
||||
return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.StudioPath, validName);
|
||||
}
|
||||
|
||||
private string GetRebasedPath()
|
||||
{
|
||||
return GetPath(System.IO.Path.GetFileName(Path), false);
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Path = newPath;
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,24 +141,6 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
return IndexNumber != null ? IndexNumber.Value.ToString("0000") : Name;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool IsMissingSeason
|
||||
{
|
||||
get { return (IsVirtualItem) && !IsUnaired; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool IsVirtualUnaired
|
||||
{
|
||||
get { return (IsVirtualItem) && IsUnaired; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool IsSpecialSeason
|
||||
{
|
||||
get { return (IndexNumber ?? -1) == 0; }
|
||||
}
|
||||
|
||||
protected override Task<QueryResult<BaseItem>> GetItemsInternal(InternalItemsQuery query)
|
||||
{
|
||||
if (query.User == null)
|
||||
|
@ -189,19 +171,17 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
/// <returns>IEnumerable{Episode}.</returns>
|
||||
public IEnumerable<Episode> GetEpisodes(User user)
|
||||
{
|
||||
var config = user.Configuration;
|
||||
|
||||
return GetEpisodes(Series, user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
|
||||
return GetEpisodes(Series, user);
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetEpisodes(Series series, User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
|
||||
public IEnumerable<Episode> GetEpisodes(Series series, User user)
|
||||
{
|
||||
return GetEpisodes(series, user, includeMissingEpisodes, includeVirtualUnairedEpisodes, null);
|
||||
return GetEpisodes(series, user, null);
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetEpisodes(Series series, User user, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable<Episode> allSeriesEpisodes)
|
||||
public IEnumerable<Episode> GetEpisodes(Series series, User user, IEnumerable<Episode> allSeriesEpisodes)
|
||||
{
|
||||
return series.GetSeasonEpisodes(user, this, includeMissingEpisodes, includeVirtualUnairedEpisodes, allSeriesEpisodes);
|
||||
return series.GetSeasonEpisodes(user, this, allSeriesEpisodes);
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetEpisodes()
|
||||
|
|
|
@ -207,7 +207,30 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
{
|
||||
var config = user.Configuration;
|
||||
|
||||
return GetSeasons(user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
|
||||
var seriesKey = GetUniqueSeriesKey(this);
|
||||
|
||||
Logger.Debug("GetSeasons SeriesKey: {0}", seriesKey);
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
AncestorWithPresentationUniqueKey = seriesKey,
|
||||
IncludeItemTypes = new[] {typeof (Season).Name},
|
||||
SortBy = new[] {ItemSortBy.SortName}
|
||||
};
|
||||
|
||||
if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes)
|
||||
{
|
||||
query.IsVirtualItem = false;
|
||||
}
|
||||
else if (!config.DisplayMissingEpisodes)
|
||||
{
|
||||
query.IsMissing = false;
|
||||
}
|
||||
else if (!config.DisplayUnairedEpisodes)
|
||||
{
|
||||
query.IsVirtualUnaired = false;
|
||||
}
|
||||
|
||||
return LibraryManager.GetItemList(query).Cast<Season>();
|
||||
}
|
||||
|
||||
protected override Task<QueryResult<BaseItem>> GetItemsInternal(InternalItemsQuery query)
|
||||
|
@ -241,59 +264,39 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
public IEnumerable<Season> GetSeasons(User user, bool includeMissingSeasons, bool includeVirtualUnaired)
|
||||
{
|
||||
var seriesKey = GetUniqueSeriesKey(this);
|
||||
|
||||
Logger.Debug("GetSeasons SeriesKey: {0}", seriesKey);
|
||||
var seasons = LibraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
{
|
||||
AncestorWithPresentationUniqueKey = seriesKey,
|
||||
IncludeItemTypes = new[] { typeof(Season).Name },
|
||||
SortBy = new[] { ItemSortBy.SortName }
|
||||
|
||||
}).Cast<Season>().ToList();
|
||||
|
||||
|
||||
if (!includeMissingSeasons)
|
||||
{
|
||||
seasons = seasons.Where(i => !(i.IsMissingSeason)).ToList();
|
||||
}
|
||||
|
||||
if (!includeVirtualUnaired)
|
||||
{
|
||||
seasons = seasons.Where(i => !i.IsVirtualUnaired).ToList();
|
||||
}
|
||||
|
||||
return seasons;
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetEpisodes(User user)
|
||||
{
|
||||
var config = user.Configuration;
|
||||
|
||||
return GetEpisodes(user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetEpisodes(User user, bool includeMissing, bool includeVirtualUnaired)
|
||||
{
|
||||
var seriesKey = GetUniqueSeriesKey(this);
|
||||
Logger.Debug("GetEpisodes seriesKey: {0}", seriesKey);
|
||||
|
||||
var allItems = LibraryManager.GetItemList(new InternalItemsQuery(user)
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
AncestorWithPresentationUniqueKey = seriesKey,
|
||||
IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name },
|
||||
SortBy = new[] { ItemSortBy.SortName }
|
||||
IncludeItemTypes = new[] {typeof (Episode).Name, typeof (Season).Name},
|
||||
SortBy = new[] {ItemSortBy.SortName}
|
||||
};
|
||||
var config = user.Configuration;
|
||||
if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes)
|
||||
{
|
||||
query.IsVirtualItem = false;
|
||||
}
|
||||
else if (!config.DisplayMissingEpisodes)
|
||||
{
|
||||
query.IsMissing = false;
|
||||
}
|
||||
else if (!config.DisplayUnairedEpisodes)
|
||||
{
|
||||
query.IsVirtualUnaired = false;
|
||||
}
|
||||
|
||||
}).ToList();
|
||||
var allItems = LibraryManager.GetItemList(query).ToList();
|
||||
|
||||
Logger.Debug("GetEpisodes return {0} items from database", allItems.Count);
|
||||
|
||||
var allSeriesEpisodes = allItems.OfType<Episode>().ToList();
|
||||
|
||||
var allEpisodes = allItems.OfType<Season>()
|
||||
.SelectMany(i => i.GetEpisodes(this, user, includeMissing, includeVirtualUnaired, allSeriesEpisodes))
|
||||
.SelectMany(i => i.GetEpisodes(this, user, allSeriesEpisodes))
|
||||
.Reverse()
|
||||
.ToList();
|
||||
|
||||
|
@ -370,13 +373,6 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
progress.Report(100);
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetSeasonEpisodes(User user, Season season)
|
||||
{
|
||||
var config = user.Configuration;
|
||||
|
||||
return GetSeasonEpisodes(user, season, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
|
||||
}
|
||||
|
||||
private IEnumerable<Episode> GetAllEpisodes(User user)
|
||||
{
|
||||
Logger.Debug("Series.GetAllEpisodes entering GetItemList");
|
||||
|
@ -394,64 +390,53 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
return result;
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetSeasonEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes)
|
||||
public IEnumerable<Episode> GetSeasonEpisodes(User user, Season parentSeason)
|
||||
{
|
||||
IEnumerable<Episode> episodes = GetAllEpisodes(user);
|
||||
var seriesKey = GetUniqueSeriesKey(this);
|
||||
Logger.Debug("GetSeasonEpisodes seriesKey: {0}", seriesKey);
|
||||
|
||||
return GetSeasonEpisodes(user, parentSeason, includeMissingEpisodes, includeVirtualUnairedEpisodes, episodes);
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
AncestorWithPresentationUniqueKey = seriesKey,
|
||||
IncludeItemTypes = new[] { typeof(Episode).Name },
|
||||
SortBy = new[] { ItemSortBy.SortName }
|
||||
};
|
||||
var config = user.Configuration;
|
||||
if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes)
|
||||
{
|
||||
query.IsVirtualItem = false;
|
||||
}
|
||||
else if (!config.DisplayMissingEpisodes)
|
||||
{
|
||||
query.IsMissing = false;
|
||||
}
|
||||
else if (!config.DisplayUnairedEpisodes)
|
||||
{
|
||||
query.IsVirtualUnaired = false;
|
||||
}
|
||||
|
||||
var allItems = LibraryManager.GetItemList(query).OfType<Episode>();
|
||||
|
||||
return GetSeasonEpisodes(user, parentSeason, allItems);
|
||||
}
|
||||
|
||||
public IEnumerable<Episode> GetSeasonEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable<Episode> allSeriesEpisodes)
|
||||
public IEnumerable<Episode> GetSeasonEpisodes(User user, Season parentSeason, IEnumerable<Episode> allSeriesEpisodes)
|
||||
{
|
||||
if (allSeriesEpisodes == null)
|
||||
{
|
||||
Logger.Debug("GetSeasonEpisodes allSeriesEpisodes is null");
|
||||
return GetSeasonEpisodes(user, parentSeason, includeMissingEpisodes, includeVirtualUnairedEpisodes);
|
||||
return GetSeasonEpisodes(user, parentSeason);
|
||||
}
|
||||
|
||||
Logger.Debug("GetSeasonEpisodes FilterEpisodesBySeason");
|
||||
var episodes = FilterEpisodesBySeason(allSeriesEpisodes, parentSeason, ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons);
|
||||
|
||||
if (!includeMissingEpisodes)
|
||||
{
|
||||
episodes = episodes.Where(i => !i.IsMissingEpisode);
|
||||
}
|
||||
if (!includeVirtualUnairedEpisodes)
|
||||
{
|
||||
episodes = episodes.Where(i => !i.IsVirtualUnaired);
|
||||
}
|
||||
|
||||
var sortBy = (parentSeason.IndexNumber ?? -1) == 0 ? ItemSortBy.SortName : ItemSortBy.AiredEpisodeOrder;
|
||||
|
||||
return LibraryManager.Sort(episodes, user, new[] { sortBy }, SortOrder.Ascending)
|
||||
.Cast<Episode>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters the episodes by season.
|
||||
/// </summary>
|
||||
public static IEnumerable<Episode> FilterEpisodesBySeason(IEnumerable<Episode> episodes, int seasonNumber, bool includeSpecials)
|
||||
{
|
||||
if (!includeSpecials || seasonNumber < 1)
|
||||
{
|
||||
return episodes.Where(i => (i.ParentIndexNumber ?? -1) == seasonNumber);
|
||||
}
|
||||
|
||||
return episodes.Where(i =>
|
||||
{
|
||||
var episode = i;
|
||||
|
||||
if (episode != null)
|
||||
{
|
||||
var currentSeasonNumber = episode.AiredSeasonNumber;
|
||||
|
||||
return currentSeasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters the episodes by season.
|
||||
/// </summary>
|
||||
|
@ -480,6 +465,32 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters the episodes by season.
|
||||
/// </summary>
|
||||
public static IEnumerable<Episode> FilterEpisodesBySeason(IEnumerable<Episode> episodes, int seasonNumber, bool includeSpecials)
|
||||
{
|
||||
if (!includeSpecials || seasonNumber < 1)
|
||||
{
|
||||
return episodes.Where(i => (i.ParentIndexNumber ?? -1) == seasonNumber);
|
||||
}
|
||||
|
||||
return episodes.Where(i =>
|
||||
{
|
||||
var episode = i;
|
||||
|
||||
if (episode != null)
|
||||
{
|
||||
var currentSeasonNumber = episode.AiredSeasonNumber;
|
||||
|
||||
return currentSeasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
{
|
||||
return config.BlockUnratedItems.Contains(UnratedItem.Series);
|
||||
|
|
|
@ -1100,8 +1100,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
bool? isVirtualUnaired,
|
||||
bool? isUnaired)
|
||||
{
|
||||
items = FilterVirtualSeasons(items, isMissing, isVirtualUnaired, isUnaired);
|
||||
|
||||
if (isMissing.HasValue)
|
||||
{
|
||||
var val = isMissing.Value;
|
||||
|
@ -1147,57 +1145,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
return items;
|
||||
}
|
||||
|
||||
private static IEnumerable<BaseItem> FilterVirtualSeasons(
|
||||
IEnumerable<BaseItem> items,
|
||||
bool? isMissing,
|
||||
bool? isVirtualUnaired,
|
||||
bool? isUnaired)
|
||||
{
|
||||
if (isMissing.HasValue)
|
||||
{
|
||||
var val = isMissing.Value;
|
||||
items = items.Where(i =>
|
||||
{
|
||||
var e = i as Season;
|
||||
if (e != null)
|
||||
{
|
||||
return (e.IsMissingSeason) == val;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (isUnaired.HasValue)
|
||||
{
|
||||
var val = isUnaired.Value;
|
||||
items = items.Where(i =>
|
||||
{
|
||||
var e = i as Season;
|
||||
if (e != null)
|
||||
{
|
||||
return e.IsUnaired == val;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (isVirtualUnaired.HasValue)
|
||||
{
|
||||
var val = isVirtualUnaired.Value;
|
||||
items = items.Where(i =>
|
||||
{
|
||||
var e = i as Season;
|
||||
if (e != null)
|
||||
{
|
||||
return e.IsVirtualUnaired == val;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public static QueryResult<BaseItem> SortAndPage(IEnumerable<BaseItem> items,
|
||||
int? totalRecordLimit,
|
||||
InternalItemsQuery query,
|
||||
|
|
|
@ -112,5 +112,48 @@ namespace MediaBrowser.Controller.Entities
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName = true)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validName = normalizeName ?
|
||||
FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
|
||||
name;
|
||||
|
||||
return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.YearPath, validName);
|
||||
}
|
||||
|
||||
private string GetRebasedPath()
|
||||
{
|
||||
return GetPath(System.IO.Path.GetFileName(Path), false);
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Path = newPath;
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,5 +106,7 @@ namespace MediaBrowser.Controller
|
|||
/// </summary>
|
||||
/// <value>The internal metadata path.</value>
|
||||
string InternalMetadataPath { get; }
|
||||
|
||||
string ArtistsPath { get; }
|
||||
}
|
||||
}
|
|
@ -343,14 +343,16 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
// If that doesn't pan out, then do a recursive search
|
||||
var files = Directory.GetFiles(path);
|
||||
|
||||
var ffmpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase));
|
||||
var ffprobePath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffprobe", StringComparison.OrdinalIgnoreCase));
|
||||
var excludeExtensions = new[] { ".c" };
|
||||
|
||||
var ffmpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase) && !excludeExtensions.Contains(Path.GetExtension(i) ?? string.Empty));
|
||||
var ffprobePath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffprobe", StringComparison.OrdinalIgnoreCase) && !excludeExtensions.Contains(Path.GetExtension(i) ?? string.Empty));
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ffmpegPath) || !File.Exists(ffmpegPath))
|
||||
{
|
||||
files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
|
||||
|
||||
ffmpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase));
|
||||
ffmpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase) && !excludeExtensions.Contains(Path.GetExtension(i) ?? string.Empty));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(ffmpegPath))
|
||||
{
|
||||
|
|
|
@ -42,6 +42,13 @@ namespace MediaBrowser.Providers.Manager
|
|||
var config = ProviderManager.GetMetadataOptions(item);
|
||||
|
||||
var updateType = ItemUpdateType.None;
|
||||
var requiresRefresh = false;
|
||||
|
||||
if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None)
|
||||
{
|
||||
// TODO: If this returns true, should we instead just change metadata refresh mode to Full?
|
||||
requiresRefresh = item.RequiresRefresh();
|
||||
}
|
||||
|
||||
var itemImageProvider = new ItemImageProvider(Logger, ProviderManager, ServerConfigurationManager, FileSystem);
|
||||
var localImagesFailed = false;
|
||||
|
@ -70,14 +77,10 @@ namespace MediaBrowser.Providers.Manager
|
|||
|
||||
bool hasRefreshedMetadata = true;
|
||||
bool hasRefreshedImages = true;
|
||||
var requiresRefresh = false;
|
||||
|
||||
// Next run metadata providers
|
||||
if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None)
|
||||
{
|
||||
// TODO: If this returns true, should we instead just change metadata refresh mode to Full?
|
||||
requiresRefresh = item.RequiresRefresh();
|
||||
|
||||
var providers = GetProviders(item, refreshOptions, requiresRefresh)
|
||||
.ToList();
|
||||
|
||||
|
|
|
@ -955,20 +955,23 @@ namespace MediaBrowser.Server.Implementations.Dto
|
|||
dto.Genres = item.Genres;
|
||||
}
|
||||
|
||||
dto.ImageTags = new Dictionary<ImageType, string>();
|
||||
|
||||
// Prevent implicitly captured closure
|
||||
var currentItem = item;
|
||||
foreach (var image in currentItem.ImageInfos.Where(i => !currentItem.AllowsMultipleImages(i.Type))
|
||||
.ToList())
|
||||
if (options.EnableImages)
|
||||
{
|
||||
if (options.GetImageLimit(image.Type) > 0)
|
||||
{
|
||||
var tag = GetImageCacheTag(item, image);
|
||||
dto.ImageTags = new Dictionary<ImageType, string>();
|
||||
|
||||
if (tag != null)
|
||||
// Prevent implicitly captured closure
|
||||
var currentItem = item;
|
||||
foreach (var image in currentItem.ImageInfos.Where(i => !currentItem.AllowsMultipleImages(i.Type))
|
||||
.ToList())
|
||||
{
|
||||
if (options.GetImageLimit(image.Type) > 0)
|
||||
{
|
||||
dto.ImageTags[image.Type] = tag;
|
||||
var tag = GetImageCacheTag(item, image);
|
||||
|
||||
if (tag != null)
|
||||
{
|
||||
dto.ImageTags[image.Type] = tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1527,97 +1530,6 @@ namespace MediaBrowser.Server.Implementations.Dto
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Since it can be slow to make all of these calculations independently, this method will provide a way to do them all at once
|
||||
/// </summary>
|
||||
/// <param name="folder">The folder.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="dto">The dto.</param>
|
||||
/// <param name="fields">The fields.</param>
|
||||
/// <param name="syncProgress">The synchronize progress.</param>
|
||||
/// <returns>Task.</returns>
|
||||
private async Task SetSpecialCounts(Folder folder, User user, BaseItemDto dto, List<ItemFields> fields, Dictionary<string, SyncJobItemStatus> syncProgress)
|
||||
{
|
||||
var recursiveItemCount = 0;
|
||||
var unplayed = 0;
|
||||
|
||||
double totalPercentPlayed = 0;
|
||||
double totalSyncPercent = 0;
|
||||
|
||||
var children = await folder.GetItems(new InternalItemsQuery
|
||||
{
|
||||
IsFolder = false,
|
||||
Recursive = true,
|
||||
ExcludeLocationTypes = new[] { LocationType.Virtual },
|
||||
User = user
|
||||
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
// Loop through each recursive child
|
||||
foreach (var child in children.Items)
|
||||
{
|
||||
var userdata = _userDataRepository.GetUserData(user, child);
|
||||
|
||||
recursiveItemCount++;
|
||||
|
||||
var isUnplayed = true;
|
||||
|
||||
// Incrememt totalPercentPlayed
|
||||
if (userdata != null)
|
||||
{
|
||||
if (userdata.Played)
|
||||
{
|
||||
totalPercentPlayed += 100;
|
||||
|
||||
isUnplayed = false;
|
||||
}
|
||||
else if (userdata.PlaybackPositionTicks > 0 && child.RunTimeTicks.HasValue && child.RunTimeTicks.Value > 0)
|
||||
{
|
||||
double itemPercent = userdata.PlaybackPositionTicks;
|
||||
itemPercent /= child.RunTimeTicks.Value;
|
||||
totalPercentPlayed += itemPercent;
|
||||
}
|
||||
}
|
||||
|
||||
if (isUnplayed)
|
||||
{
|
||||
unplayed++;
|
||||
}
|
||||
|
||||
double percent = 0;
|
||||
SyncJobItemStatus syncItemProgress;
|
||||
if (syncProgress.TryGetValue(child.Id.ToString("N"), out syncItemProgress))
|
||||
{
|
||||
switch (syncItemProgress)
|
||||
{
|
||||
case SyncJobItemStatus.Synced:
|
||||
percent = 100;
|
||||
break;
|
||||
case SyncJobItemStatus.Converting:
|
||||
case SyncJobItemStatus.ReadyToTransfer:
|
||||
case SyncJobItemStatus.Transferring:
|
||||
percent = 50;
|
||||
break;
|
||||
}
|
||||
}
|
||||
totalSyncPercent += percent;
|
||||
}
|
||||
|
||||
dto.RecursiveItemCount = recursiveItemCount;
|
||||
dto.UserData.UnplayedItemCount = unplayed;
|
||||
|
||||
if (recursiveItemCount > 0)
|
||||
{
|
||||
dto.UserData.PlayedPercentage = totalPercentPlayed / recursiveItemCount;
|
||||
|
||||
var pct = totalSyncPercent / recursiveItemCount;
|
||||
if (pct > 0)
|
||||
{
|
||||
dto.SyncPercent = pct;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the primary image aspect ratio.
|
||||
/// </summary>
|
||||
|
|
|
@ -829,7 +829,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <returns>Task{Person}.</returns>
|
||||
public Person GetPerson(string name)
|
||||
{
|
||||
return GetItemByName<Person>(ConfigurationManager.ApplicationPaths.PeoplePath, name);
|
||||
return CreateItemByName<Person>(Person.GetPath(name), name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -839,7 +839,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <returns>Task{Studio}.</returns>
|
||||
public Studio GetStudio(string name)
|
||||
{
|
||||
return GetItemByName<Studio>(ConfigurationManager.ApplicationPaths.StudioPath, name);
|
||||
return CreateItemByName<Studio>(Studio.GetPath(name), name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -849,7 +849,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <returns>Task{Genre}.</returns>
|
||||
public Genre GetGenre(string name)
|
||||
{
|
||||
return GetItemByName<Genre>(ConfigurationManager.ApplicationPaths.GenrePath, name);
|
||||
return CreateItemByName<Genre>(Genre.GetPath(name), name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -859,7 +859,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <returns>Task{MusicGenre}.</returns>
|
||||
public MusicGenre GetMusicGenre(string name)
|
||||
{
|
||||
return GetItemByName<MusicGenre>(ConfigurationManager.ApplicationPaths.MusicGenrePath, name);
|
||||
return CreateItemByName<MusicGenre>(MusicGenre.GetPath(name), name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -869,14 +869,9 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <returns>Task{GameGenre}.</returns>
|
||||
public GameGenre GetGameGenre(string name)
|
||||
{
|
||||
return GetItemByName<GameGenre>(ConfigurationManager.ApplicationPaths.GameGenrePath, name);
|
||||
return CreateItemByName<GameGenre>(GameGenre.GetPath(name), name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The us culture
|
||||
/// </summary>
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Year
|
||||
/// </summary>
|
||||
|
@ -890,19 +885,9 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
throw new ArgumentOutOfRangeException("Years less than or equal to 0 are invalid.");
|
||||
}
|
||||
|
||||
return GetItemByName<Year>(ConfigurationManager.ApplicationPaths.YearPath, value.ToString(UsCulture));
|
||||
}
|
||||
var name = value.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the artists path.
|
||||
/// </summary>
|
||||
/// <value>The artists path.</value>
|
||||
public string ArtistsPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(ConfigurationManager.ApplicationPaths.ItemsByNamePath, "artists");
|
||||
}
|
||||
return CreateItemByName<Year>(Year.GetPath(name), name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -912,48 +897,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <returns>Task{Genre}.</returns>
|
||||
public MusicArtist GetArtist(string name)
|
||||
{
|
||||
return GetItemByName<MusicArtist>(ArtistsPath, name);
|
||||
}
|
||||
|
||||
private T GetItemByName<T>(string path, string name)
|
||||
where T : BaseItem, new()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
throw new ArgumentNullException("path");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw new ArgumentNullException("name");
|
||||
}
|
||||
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validFilename = _fileSystem.GetValidFilename(name)
|
||||
.Trim()
|
||||
.TrimEnd('.');
|
||||
|
||||
string subFolderPrefix = null;
|
||||
|
||||
var type = typeof(T);
|
||||
|
||||
if (type == typeof(Person))
|
||||
{
|
||||
foreach (char c in validFilename)
|
||||
{
|
||||
if (char.IsLetterOrDigit(c))
|
||||
{
|
||||
subFolderPrefix = c.ToString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var fullPath = string.IsNullOrEmpty(subFolderPrefix) ?
|
||||
Path.Combine(path, validFilename) :
|
||||
Path.Combine(path, subFolderPrefix, validFilename);
|
||||
|
||||
return CreateItemByName<T>(fullPath, name);
|
||||
return CreateItemByName<MusicArtist>(MusicArtist.GetPath(name), name);
|
||||
}
|
||||
|
||||
private T CreateItemByName<T>(string path, string name)
|
||||
|
|
|
@ -166,12 +166,12 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
ExcludeItemTypes = excludeItemTypes.ToArray(),
|
||||
IncludeItemTypes = includeItemTypes.ToArray(),
|
||||
Limit = query.Limit,
|
||||
IncludeItemsByName = true
|
||||
|
||||
IncludeItemsByName = true,
|
||||
IsVirtualItem = false
|
||||
});
|
||||
|
||||
// Add search hints based on item name
|
||||
hints.AddRange(mediaItems.Where(IncludeInSearch).Select(item =>
|
||||
hints.AddRange(mediaItems.Select(item =>
|
||||
{
|
||||
var index = GetIndex(item.Name, searchTerm, terms);
|
||||
|
||||
|
@ -187,20 +187,6 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
return Task.FromResult(returnValue);
|
||||
}
|
||||
|
||||
private bool IncludeInSearch(BaseItem item)
|
||||
{
|
||||
var episode = item as Episode;
|
||||
|
||||
if (episode != null)
|
||||
{
|
||||
if (episode.IsMissingEpisode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index.
|
||||
/// </summary>
|
||||
|
|
|
@ -3095,6 +3095,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||
whereClauses.Add("LocationType<>'Virtual'");
|
||||
}
|
||||
}
|
||||
if (query.IsSpecialSeason.HasValue)
|
||||
{
|
||||
if (query.IsSpecialSeason.Value)
|
||||
{
|
||||
whereClauses.Add("IndexNumber = 0");
|
||||
}
|
||||
else
|
||||
{
|
||||
whereClauses.Add("IndexNumber <> 0");
|
||||
}
|
||||
}
|
||||
if (query.IsUnaired.HasValue)
|
||||
{
|
||||
if (query.IsUnaired.Value)
|
||||
|
|
|
@ -88,6 +88,14 @@ namespace MediaBrowser.Server.Implementations
|
|||
}
|
||||
}
|
||||
|
||||
public string ArtistsPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(ItemsByNamePath, "artists");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the Genre directory
|
||||
/// </summary>
|
||||
|
|
|
@ -1001,7 +1001,8 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
var series = episode.Series;
|
||||
if (series != null)
|
||||
{
|
||||
var episodes = series.GetEpisodes(user, false, false)
|
||||
var episodes = series.GetEpisodes(user)
|
||||
.Where(i => !i.IsVirtualItem)
|
||||
.SkipWhile(i => i.Id != episode.Id)
|
||||
.ToList();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user