mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-06-23 15:30:56 -04:00
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);
|
throw new ResourceNotFoundException("No series exists with Id " + request.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
var seasons = series.GetSeasons(user);
|
var seasons = (await series.GetItems(new InternalItemsQuery(user)
|
||||||
|
|
||||||
if (request.IsSpecialSeason.HasValue)
|
|
||||||
{
|
{
|
||||||
var val = request.IsSpecialSeason.Value;
|
IsMissing = request.IsMissing,
|
||||||
|
IsVirtualUnaired = request.IsVirtualUnaired,
|
||||||
|
IsSpecialSeason = request.IsSpecialSeason,
|
||||||
|
AdjacentTo = request.AdjacentTo
|
||||||
|
|
||||||
seasons = seasons.Where(i => i.IsSpecialSeason == val);
|
}).ConfigureAwait(false)).Items.OfType<Season>();
|
||||||
}
|
|
||||||
|
|
||||||
seasons = FilterVirtualSeasons(request, seasons);
|
|
||||||
|
|
||||||
// This must be the last filter
|
|
||||||
if (!string.IsNullOrEmpty(request.AdjacentTo))
|
|
||||||
{
|
|
||||||
seasons = UserViewBuilder.FilterForAdjacency(seasons, request.AdjacentTo)
|
|
||||||
.Cast<Season>();
|
|
||||||
}
|
|
||||||
|
|
||||||
var dtoOptions = GetDtoOptions(request);
|
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)
|
public async Task<object> Get(GetEpisodes request)
|
||||||
{
|
{
|
||||||
var user = _userManager.GetUserById(request.UserId);
|
var user = _userManager.GetUserById(request.UserId);
|
||||||
|
@ -270,5 +270,54 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||||||
return false;
|
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);
|
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;
|
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;
|
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[] Genres { get; set; }
|
||||||
public string[] Keywords { get; set; }
|
public string[] Keywords { get; set; }
|
||||||
|
|
||||||
|
public bool? IsSpecialSeason { get; set; }
|
||||||
public bool? IsMissing { get; set; }
|
public bool? IsMissing { get; set; }
|
||||||
public bool? IsUnaired { get; set; }
|
public bool? IsUnaired { get; set; }
|
||||||
public bool? IsVirtualUnaired { get; set; }
|
public bool? IsVirtualUnaired { get; set; }
|
||||||
@ -50,6 +51,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
|
|
||||||
public string PresentationUniqueKey { get; set; }
|
public string PresentationUniqueKey { get; set; }
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
|
public string PathNotStartsWith { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string SlugName { get; set; }
|
public string SlugName { get; set; }
|
||||||
|
|
||||||
|
@ -122,6 +122,64 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return false;
|
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>
|
/// <summary>
|
||||||
|
@ -85,5 +85,48 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return false;
|
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;
|
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)
|
protected override Task<QueryResult<BaseItem>> GetItemsInternal(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
if (query.User == null)
|
if (query.User == null)
|
||||||
@ -189,19 +171,17 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||||||
/// <returns>IEnumerable{Episode}.</returns>
|
/// <returns>IEnumerable{Episode}.</returns>
|
||||||
public IEnumerable<Episode> GetEpisodes(User user)
|
public IEnumerable<Episode> GetEpisodes(User user)
|
||||||
{
|
{
|
||||||
var config = user.Configuration;
|
return GetEpisodes(Series, user);
|
||||||
|
|
||||||
return GetEpisodes(Series, user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
public IEnumerable<Episode> GetEpisodes()
|
||||||
|
@ -207,7 +207,30 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||||||
{
|
{
|
||||||
var config = user.Configuration;
|
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)
|
protected override Task<QueryResult<BaseItem>> GetItemsInternal(InternalItemsQuery query)
|
||||||
@ -241,59 +264,39 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||||||
return Task.FromResult(result);
|
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)
|
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);
|
var seriesKey = GetUniqueSeriesKey(this);
|
||||||
Logger.Debug("GetEpisodes seriesKey: {0}", seriesKey);
|
Logger.Debug("GetEpisodes seriesKey: {0}", seriesKey);
|
||||||
|
|
||||||
var allItems = LibraryManager.GetItemList(new InternalItemsQuery(user)
|
var query = new InternalItemsQuery(user)
|
||||||
{
|
{
|
||||||
AncestorWithPresentationUniqueKey = seriesKey,
|
AncestorWithPresentationUniqueKey = seriesKey,
|
||||||
IncludeItemTypes = new[] {typeof (Episode).Name, typeof (Season).Name},
|
IncludeItemTypes = new[] {typeof (Episode).Name, typeof (Season).Name},
|
||||||
SortBy = new[] {ItemSortBy.SortName}
|
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);
|
Logger.Debug("GetEpisodes return {0} items from database", allItems.Count);
|
||||||
|
|
||||||
var allSeriesEpisodes = allItems.OfType<Episode>().ToList();
|
var allSeriesEpisodes = allItems.OfType<Episode>().ToList();
|
||||||
|
|
||||||
var allEpisodes = allItems.OfType<Season>()
|
var allEpisodes = allItems.OfType<Season>()
|
||||||
.SelectMany(i => i.GetEpisodes(this, user, includeMissing, includeVirtualUnaired, allSeriesEpisodes))
|
.SelectMany(i => i.GetEpisodes(this, user, allSeriesEpisodes))
|
||||||
.Reverse()
|
.Reverse()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
@ -370,13 +373,6 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||||||
progress.Report(100);
|
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)
|
private IEnumerable<Episode> GetAllEpisodes(User user)
|
||||||
{
|
{
|
||||||
Logger.Debug("Series.GetAllEpisodes entering GetItemList");
|
Logger.Debug("Series.GetAllEpisodes entering GetItemList");
|
||||||
@ -394,64 +390,53 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||||||
return result;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Episode> GetSeasonEpisodes(User user, Season parentSeason, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable<Episode> allSeriesEpisodes)
|
var allItems = LibraryManager.GetItemList(query).OfType<Episode>();
|
||||||
|
|
||||||
|
return GetSeasonEpisodes(user, parentSeason, allItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Episode> GetSeasonEpisodes(User user, Season parentSeason, IEnumerable<Episode> allSeriesEpisodes)
|
||||||
{
|
{
|
||||||
if (allSeriesEpisodes == null)
|
if (allSeriesEpisodes == null)
|
||||||
{
|
{
|
||||||
Logger.Debug("GetSeasonEpisodes allSeriesEpisodes is null");
|
Logger.Debug("GetSeasonEpisodes allSeriesEpisodes is null");
|
||||||
return GetSeasonEpisodes(user, parentSeason, includeMissingEpisodes, includeVirtualUnairedEpisodes);
|
return GetSeasonEpisodes(user, parentSeason);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Debug("GetSeasonEpisodes FilterEpisodesBySeason");
|
Logger.Debug("GetSeasonEpisodes FilterEpisodesBySeason");
|
||||||
var episodes = FilterEpisodesBySeason(allSeriesEpisodes, parentSeason, ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons);
|
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;
|
var sortBy = (parentSeason.IndexNumber ?? -1) == 0 ? ItemSortBy.SortName : ItemSortBy.AiredEpisodeOrder;
|
||||||
|
|
||||||
return LibraryManager.Sort(episodes, user, new[] { sortBy }, SortOrder.Ascending)
|
return LibraryManager.Sort(episodes, user, new[] { sortBy }, SortOrder.Ascending)
|
||||||
.Cast<Episode>();
|
.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>
|
/// <summary>
|
||||||
/// Filters the episodes by season.
|
/// Filters the episodes by season.
|
||||||
/// </summary>
|
/// </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)
|
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||||
{
|
{
|
||||||
return config.BlockUnratedItems.Contains(UnratedItem.Series);
|
return config.BlockUnratedItems.Contains(UnratedItem.Series);
|
||||||
|
@ -1100,8 +1100,6 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
bool? isVirtualUnaired,
|
bool? isVirtualUnaired,
|
||||||
bool? isUnaired)
|
bool? isUnaired)
|
||||||
{
|
{
|
||||||
items = FilterVirtualSeasons(items, isMissing, isVirtualUnaired, isUnaired);
|
|
||||||
|
|
||||||
if (isMissing.HasValue)
|
if (isMissing.HasValue)
|
||||||
{
|
{
|
||||||
var val = isMissing.Value;
|
var val = isMissing.Value;
|
||||||
@ -1147,57 +1145,6 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return items;
|
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,
|
public static QueryResult<BaseItem> SortAndPage(IEnumerable<BaseItem> items,
|
||||||
int? totalRecordLimit,
|
int? totalRecordLimit,
|
||||||
InternalItemsQuery query,
|
InternalItemsQuery query,
|
||||||
|
@ -112,5 +112,48 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return false;
|
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>
|
/// </summary>
|
||||||
/// <value>The internal metadata path.</value>
|
/// <value>The internal metadata path.</value>
|
||||||
string InternalMetadataPath { get; }
|
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
|
// If that doesn't pan out, then do a recursive search
|
||||||
var files = Directory.GetFiles(path);
|
var files = Directory.GetFiles(path);
|
||||||
|
|
||||||
var ffmpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase));
|
var excludeExtensions = new[] { ".c" };
|
||||||
var ffprobePath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffprobe", StringComparison.OrdinalIgnoreCase));
|
|
||||||
|
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))
|
if (string.IsNullOrWhiteSpace(ffmpegPath) || !File.Exists(ffmpegPath))
|
||||||
{
|
{
|
||||||
files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
|
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))
|
if (!string.IsNullOrWhiteSpace(ffmpegPath))
|
||||||
{
|
{
|
||||||
|
@ -42,6 +42,13 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
var config = ProviderManager.GetMetadataOptions(item);
|
var config = ProviderManager.GetMetadataOptions(item);
|
||||||
|
|
||||||
var updateType = ItemUpdateType.None;
|
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 itemImageProvider = new ItemImageProvider(Logger, ProviderManager, ServerConfigurationManager, FileSystem);
|
||||||
var localImagesFailed = false;
|
var localImagesFailed = false;
|
||||||
@ -70,14 +77,10 @@ namespace MediaBrowser.Providers.Manager
|
|||||||
|
|
||||||
bool hasRefreshedMetadata = true;
|
bool hasRefreshedMetadata = true;
|
||||||
bool hasRefreshedImages = true;
|
bool hasRefreshedImages = true;
|
||||||
var requiresRefresh = false;
|
|
||||||
|
|
||||||
// Next run metadata providers
|
// Next run metadata providers
|
||||||
if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None)
|
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)
|
var providers = GetProviders(item, refreshOptions, requiresRefresh)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
@ -955,6 +955,8 @@ namespace MediaBrowser.Server.Implementations.Dto
|
|||||||
dto.Genres = item.Genres;
|
dto.Genres = item.Genres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.EnableImages)
|
||||||
|
{
|
||||||
dto.ImageTags = new Dictionary<ImageType, string>();
|
dto.ImageTags = new Dictionary<ImageType, string>();
|
||||||
|
|
||||||
// Prevent implicitly captured closure
|
// Prevent implicitly captured closure
|
||||||
@ -972,6 +974,7 @@ namespace MediaBrowser.Server.Implementations.Dto
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dto.Id = GetDtoId(item);
|
dto.Id = GetDtoId(item);
|
||||||
dto.IndexNumber = item.IndexNumber;
|
dto.IndexNumber = item.IndexNumber;
|
||||||
@ -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>
|
/// <summary>
|
||||||
/// Attaches the primary image aspect ratio.
|
/// Attaches the primary image aspect ratio.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -829,7 +829,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||||||
/// <returns>Task{Person}.</returns>
|
/// <returns>Task{Person}.</returns>
|
||||||
public Person GetPerson(string name)
|
public Person GetPerson(string name)
|
||||||
{
|
{
|
||||||
return GetItemByName<Person>(ConfigurationManager.ApplicationPaths.PeoplePath, name);
|
return CreateItemByName<Person>(Person.GetPath(name), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -839,7 +839,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||||||
/// <returns>Task{Studio}.</returns>
|
/// <returns>Task{Studio}.</returns>
|
||||||
public Studio GetStudio(string name)
|
public Studio GetStudio(string name)
|
||||||
{
|
{
|
||||||
return GetItemByName<Studio>(ConfigurationManager.ApplicationPaths.StudioPath, name);
|
return CreateItemByName<Studio>(Studio.GetPath(name), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -849,7 +849,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||||||
/// <returns>Task{Genre}.</returns>
|
/// <returns>Task{Genre}.</returns>
|
||||||
public Genre GetGenre(string name)
|
public Genre GetGenre(string name)
|
||||||
{
|
{
|
||||||
return GetItemByName<Genre>(ConfigurationManager.ApplicationPaths.GenrePath, name);
|
return CreateItemByName<Genre>(Genre.GetPath(name), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -859,7 +859,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||||||
/// <returns>Task{MusicGenre}.</returns>
|
/// <returns>Task{MusicGenre}.</returns>
|
||||||
public MusicGenre GetMusicGenre(string name)
|
public MusicGenre GetMusicGenre(string name)
|
||||||
{
|
{
|
||||||
return GetItemByName<MusicGenre>(ConfigurationManager.ApplicationPaths.MusicGenrePath, name);
|
return CreateItemByName<MusicGenre>(MusicGenre.GetPath(name), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -869,14 +869,9 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||||||
/// <returns>Task{GameGenre}.</returns>
|
/// <returns>Task{GameGenre}.</returns>
|
||||||
public GameGenre GetGameGenre(string name)
|
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>
|
/// <summary>
|
||||||
/// Gets a Year
|
/// Gets a Year
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -890,19 +885,9 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||||||
throw new ArgumentOutOfRangeException("Years less than or equal to 0 are invalid.");
|
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>
|
return CreateItemByName<Year>(Year.GetPath(name), name);
|
||||||
/// Gets the artists path.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The artists path.</value>
|
|
||||||
public string ArtistsPath
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Path.Combine(ConfigurationManager.ApplicationPaths.ItemsByNamePath, "artists");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -912,48 +897,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||||||
/// <returns>Task{Genre}.</returns>
|
/// <returns>Task{Genre}.</returns>
|
||||||
public MusicArtist GetArtist(string name)
|
public MusicArtist GetArtist(string name)
|
||||||
{
|
{
|
||||||
return GetItemByName<MusicArtist>(ArtistsPath, name);
|
return CreateItemByName<MusicArtist>(MusicArtist.GetPath(name), 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private T CreateItemByName<T>(string path, string name)
|
private T CreateItemByName<T>(string path, string name)
|
||||||
|
@ -166,12 +166,12 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||||||
ExcludeItemTypes = excludeItemTypes.ToArray(),
|
ExcludeItemTypes = excludeItemTypes.ToArray(),
|
||||||
IncludeItemTypes = includeItemTypes.ToArray(),
|
IncludeItemTypes = includeItemTypes.ToArray(),
|
||||||
Limit = query.Limit,
|
Limit = query.Limit,
|
||||||
IncludeItemsByName = true
|
IncludeItemsByName = true,
|
||||||
|
IsVirtualItem = false
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add search hints based on item name
|
// 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);
|
var index = GetIndex(item.Name, searchTerm, terms);
|
||||||
|
|
||||||
@ -187,20 +187,6 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||||||
return Task.FromResult(returnValue);
|
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>
|
/// <summary>
|
||||||
/// Gets the index.
|
/// Gets the index.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -3095,6 +3095,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
|||||||
whereClauses.Add("LocationType<>'Virtual'");
|
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.HasValue)
|
||||||
{
|
{
|
||||||
if (query.IsUnaired.Value)
|
if (query.IsUnaired.Value)
|
||||||
|
@ -88,6 +88,14 @@ namespace MediaBrowser.Server.Implementations
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string ArtistsPath
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Path.Combine(ItemsByNamePath, "artists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the path to the Genre directory
|
/// Gets the path to the Genre directory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1001,7 +1001,8 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||||||
var series = episode.Series;
|
var series = episode.Series;
|
||||||
if (series != null)
|
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)
|
.SkipWhile(i => i.Id != episode.Id)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user