mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-07-09 03:04:24 -04:00
restore changes
This commit is contained in:
parent
3ebcc9d599
commit
9cdb4ac242
@ -24,6 +24,7 @@ using System.Runtime.Serialization;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CommonIO;
|
using CommonIO;
|
||||||
|
using MediaBrowser.Model.LiveTv;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Entities
|
namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
@ -34,6 +35,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
{
|
{
|
||||||
protected BaseItem()
|
protected BaseItem()
|
||||||
{
|
{
|
||||||
|
Tags = new List<string>();
|
||||||
Genres = new List<string>();
|
Genres = new List<string>();
|
||||||
Studios = new List<string>();
|
Studios = new List<string>();
|
||||||
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
@ -44,7 +46,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The supported image extensions
|
/// The supported image extensions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly string[] SupportedImageExtensions = { ".png", ".jpg", ".jpeg" };
|
public static readonly string[] SupportedImageExtensions = { ".png", ".jpg", ".jpeg", ".tbn" };
|
||||||
|
|
||||||
public static readonly List<string> SupportedImageExtensionsList = SupportedImageExtensions.ToList();
|
public static readonly List<string> SupportedImageExtensionsList = SupportedImageExtensions.ToList();
|
||||||
|
|
||||||
@ -103,7 +105,8 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// Gets or sets the name.
|
/// Gets or sets the name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The name.</value>
|
/// <value>The name.</value>
|
||||||
public string Name
|
[IgnoreDataMember]
|
||||||
|
public virtual string Name
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -122,14 +125,23 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// Gets or sets the id.
|
/// Gets or sets the id.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The id.</value>
|
/// <value>The id.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether this instance is hd.
|
/// Gets or sets a value indicating whether this instance is hd.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value><c>true</c> if this instance is hd; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if this instance is hd; otherwise, <c>false</c>.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public bool? IsHD { get; set; }
|
public bool? IsHD { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the audio.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The audio.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
|
public ProgramAudio? Audio { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the id that should be used to key display prefs for this item.
|
/// Return the id that should be used to key display prefs for this item.
|
||||||
/// Default is based on the type for everything except actual generic folders.
|
/// Default is based on the type for everything except actual generic folders.
|
||||||
@ -149,6 +161,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// Gets or sets the path.
|
/// Gets or sets the path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The path.</value>
|
/// <value>The path.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public virtual string Path { get; set; }
|
public virtual string Path { get; set; }
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
@ -173,7 +186,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id of the program.
|
/// If this content came from an external service, the id of the content on that service
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public string ExternalId
|
public string ExternalId
|
||||||
@ -201,11 +214,6 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool IsHiddenFromUser(User user)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public virtual bool IsOwnedItem
|
public virtual bool IsOwnedItem
|
||||||
{
|
{
|
||||||
@ -325,12 +333,14 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// Gets or sets the date created.
|
/// Gets or sets the date created.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The date created.</value>
|
/// <value>The date created.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public DateTime DateCreated { get; set; }
|
public DateTime DateCreated { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the date modified.
|
/// Gets or sets the date modified.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The date modified.</value>
|
/// <value>The date modified.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public DateTime DateModified { get; set; }
|
public DateTime DateModified { get; set; }
|
||||||
|
|
||||||
public DateTime DateLastSaved { get; set; }
|
public DateTime DateLastSaved { get; set; }
|
||||||
@ -407,6 +417,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// Gets or sets the name of the forced sort.
|
/// Gets or sets the name of the forced sort.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The name of the forced sort.</value>
|
/// <value>The name of the forced sort.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public string ForcedSortName
|
public string ForcedSortName
|
||||||
{
|
{
|
||||||
get { return _forcedSortName; }
|
get { return _forcedSortName; }
|
||||||
@ -447,10 +458,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
{
|
{
|
||||||
var idString = Id.ToString("N");
|
var idString = Id.ToString("N");
|
||||||
|
|
||||||
if (ConfigurationManager.Configuration.EnableLibraryMetadataSubFolder)
|
basePath = System.IO.Path.Combine(basePath, "library");
|
||||||
{
|
|
||||||
basePath = System.IO.Path.Combine(basePath, "library");
|
|
||||||
}
|
|
||||||
|
|
||||||
return System.IO.Path.Combine(basePath, idString.Substring(0, 2), idString);
|
return System.IO.Path.Combine(basePath, idString.Substring(0, 2), idString);
|
||||||
}
|
}
|
||||||
@ -493,6 +501,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return sortable;
|
return sortable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
public Guid ParentId { get; set; }
|
public Guid ParentId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -502,15 +511,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public Folder Parent
|
public Folder Parent
|
||||||
{
|
{
|
||||||
get
|
get { return GetParent() as Folder; }
|
||||||
{
|
|
||||||
if (ParentId != Guid.Empty)
|
|
||||||
{
|
|
||||||
return LibraryManager.GetItemById(ParentId) as Folder;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -525,16 +526,28 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public IEnumerable<Folder> Parents
|
public IEnumerable<Folder> Parents
|
||||||
{
|
{
|
||||||
get
|
get { return GetParents().OfType<Folder>(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseItem GetParent()
|
||||||
|
{
|
||||||
|
if (ParentId != Guid.Empty)
|
||||||
{
|
{
|
||||||
var parent = Parent;
|
return LibraryManager.GetItemById(ParentId);
|
||||||
|
}
|
||||||
|
|
||||||
while (parent != null)
|
return null;
|
||||||
{
|
}
|
||||||
yield return parent;
|
|
||||||
|
|
||||||
parent = parent.Parent;
|
public IEnumerable<BaseItem> GetParents()
|
||||||
}
|
{
|
||||||
|
var parent = GetParent();
|
||||||
|
|
||||||
|
while (parent != null)
|
||||||
|
{
|
||||||
|
yield return parent;
|
||||||
|
|
||||||
|
parent = parent.GetParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,19 +559,20 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
public T FindParent<T>()
|
public T FindParent<T>()
|
||||||
where T : Folder
|
where T : Folder
|
||||||
{
|
{
|
||||||
return Parents.OfType<T>().FirstOrDefault();
|
return GetParents().OfType<T>().FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public virtual BaseItem DisplayParent
|
public virtual BaseItem DisplayParent
|
||||||
{
|
{
|
||||||
get { return Parent; }
|
get { return GetParent(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When the item first debuted. For movies this could be premiere date, episodes would be first aired
|
/// When the item first debuted. For movies this could be premiere date, episodes would be first aired
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The premiere date.</value>
|
/// <value>The premiere date.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public DateTime? PremiereDate { get; set; }
|
public DateTime? PremiereDate { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -572,31 +586,35 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// Gets or sets the display type of the media.
|
/// Gets or sets the display type of the media.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The display type of the media.</value>
|
/// <value>The display type of the media.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public string DisplayMediaType { get; set; }
|
public string DisplayMediaType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the official rating.
|
/// Gets or sets the official rating.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The official rating.</value>
|
/// <value>The official rating.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public string OfficialRating { get; set; }
|
public string OfficialRating { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the official rating description.
|
/// Gets or sets the official rating description.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The official rating description.</value>
|
/// <value>The official rating description.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public string OfficialRatingDescription { get; set; }
|
public string OfficialRatingDescription { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the custom rating.
|
/// Gets or sets the custom rating.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The custom rating.</value>
|
/// <value>The custom rating.</value>
|
||||||
//[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public string CustomRating { get; set; }
|
public string CustomRating { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the overview.
|
/// Gets or sets the overview.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The overview.</value>
|
/// <value>The overview.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -609,37 +627,48 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// Gets or sets the genres.
|
/// Gets or sets the genres.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The genres.</value>
|
/// <value>The genres.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public List<string> Genres { get; set; }
|
public List<string> Genres { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the tags.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The tags.</value>
|
||||||
|
public List<string> Tags { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the home page URL.
|
/// Gets or sets the home page URL.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The home page URL.</value>
|
/// <value>The home page URL.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public string HomePageUrl { get; set; }
|
public string HomePageUrl { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the community rating.
|
/// Gets or sets the community rating.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The community rating.</value>
|
/// <value>The community rating.</value>
|
||||||
//[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public float? CommunityRating { get; set; }
|
public float? CommunityRating { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the community rating vote count.
|
/// Gets or sets the community rating vote count.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The community rating vote count.</value>
|
/// <value>The community rating vote count.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public int? VoteCount { get; set; }
|
public int? VoteCount { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the run time ticks.
|
/// Gets or sets the run time ticks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The run time ticks.</value>
|
/// <value>The run time ticks.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public long? RunTimeTicks { get; set; }
|
public long? RunTimeTicks { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the production year.
|
/// Gets or sets the production year.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The production year.</value>
|
/// <value>The production year.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public int? ProductionYear { get; set; }
|
public int? ProductionYear { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -647,19 +676,34 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
/// This could be episode number, album track number, etc.
|
/// This could be episode number, album track number, etc.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The index number.</value>
|
/// <value>The index number.</value>
|
||||||
//[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public int? IndexNumber { get; set; }
|
public int? IndexNumber { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For an episode this could be the season number, or for a song this could be the disc number.
|
/// For an episode this could be the season number, or for a song this could be the disc number.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The parent index number.</value>
|
/// <value>The parent index number.</value>
|
||||||
|
[IgnoreDataMember]
|
||||||
public int? ParentIndexNumber { get; set; }
|
public int? ParentIndexNumber { get; set; }
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public virtual string OfficialRatingForComparison
|
public string OfficialRatingForComparison
|
||||||
{
|
{
|
||||||
get { return OfficialRating; }
|
get
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(OfficialRating))
|
||||||
|
{
|
||||||
|
return OfficialRating;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parent = DisplayParent;
|
||||||
|
if (parent != null)
|
||||||
|
{
|
||||||
|
return parent.OfficialRatingForComparison;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
@ -721,21 +765,21 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return LibraryManager.ResolvePaths(files, directoryService, null)
|
return LibraryManager.ResolvePaths(files, directoryService, null)
|
||||||
.OfType<Audio.Audio>()
|
.OfType<Audio.Audio>()
|
||||||
.Select(audio =>
|
.Select(audio =>
|
||||||
{
|
|
||||||
// Try to retrieve it from the db. If we don't find it, use the resolved version
|
|
||||||
var dbItem = LibraryManager.GetItemById(audio.Id) as Audio.Audio;
|
|
||||||
|
|
||||||
if (dbItem != null)
|
|
||||||
{
|
{
|
||||||
audio = dbItem;
|
// Try to retrieve it from the db. If we don't find it, use the resolved version
|
||||||
}
|
var dbItem = LibraryManager.GetItemById(audio.Id) as Audio.Audio;
|
||||||
|
|
||||||
audio.ExtraType = ExtraType.ThemeSong;
|
if (dbItem != null)
|
||||||
|
{
|
||||||
|
audio = dbItem;
|
||||||
|
}
|
||||||
|
|
||||||
return audio;
|
audio.ExtraType = ExtraType.ThemeSong;
|
||||||
|
|
||||||
// Sort them so that the list can be easily compared for changes
|
return audio;
|
||||||
}).OrderBy(i => i.Path).ToList();
|
|
||||||
|
// Sort them so that the list can be easily compared for changes
|
||||||
|
}).OrderBy(i => i.Path).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -751,21 +795,21 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return LibraryManager.ResolvePaths(files, directoryService, null)
|
return LibraryManager.ResolvePaths(files, directoryService, null)
|
||||||
.OfType<Video>()
|
.OfType<Video>()
|
||||||
.Select(item =>
|
.Select(item =>
|
||||||
{
|
|
||||||
// Try to retrieve it from the db. If we don't find it, use the resolved version
|
|
||||||
var dbItem = LibraryManager.GetItemById(item.Id) as Video;
|
|
||||||
|
|
||||||
if (dbItem != null)
|
|
||||||
{
|
{
|
||||||
item = dbItem;
|
// Try to retrieve it from the db. If we don't find it, use the resolved version
|
||||||
}
|
var dbItem = LibraryManager.GetItemById(item.Id) as Video;
|
||||||
|
|
||||||
item.ExtraType = ExtraType.ThemeVideo;
|
if (dbItem != null)
|
||||||
|
{
|
||||||
|
item = dbItem;
|
||||||
|
}
|
||||||
|
|
||||||
return item;
|
item.ExtraType = ExtraType.ThemeVideo;
|
||||||
|
|
||||||
// Sort them so that the list can be easily compared for changes
|
return item;
|
||||||
}).OrderBy(i => i.Path).ToList();
|
|
||||||
|
// Sort them so that the list can be easily compared for changes
|
||||||
|
}).OrderBy(i => i.Path).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task RefreshMetadata(CancellationToken cancellationToken)
|
public Task RefreshMetadata(CancellationToken cancellationToken)
|
||||||
@ -821,7 +865,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
protected virtual bool SupportsOwnedItems
|
protected virtual bool SupportsOwnedItems
|
||||||
{
|
{
|
||||||
get { return IsFolder || Parent != null; }
|
get { return IsFolder || GetParent() != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
@ -846,7 +890,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
|
|
||||||
var localTrailersChanged = false;
|
var localTrailersChanged = false;
|
||||||
|
|
||||||
if (LocationType == LocationType.FileSystem && Parent != null)
|
if (LocationType == LocationType.FileSystem && GetParent() != null)
|
||||||
{
|
{
|
||||||
var hasThemeMedia = this as IHasThemeMedia;
|
var hasThemeMedia = this as IHasThemeMedia;
|
||||||
if (hasThemeMedia != null)
|
if (hasThemeMedia != null)
|
||||||
@ -1008,7 +1052,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(lang))
|
if (string.IsNullOrWhiteSpace(lang))
|
||||||
{
|
{
|
||||||
lang = Parents
|
lang = GetParents()
|
||||||
.Select(i => i.PreferredMetadataLanguage)
|
.Select(i => i.PreferredMetadataLanguage)
|
||||||
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
|
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
|
||||||
}
|
}
|
||||||
@ -1038,7 +1082,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(lang))
|
if (string.IsNullOrWhiteSpace(lang))
|
||||||
{
|
{
|
||||||
lang = Parents
|
lang = GetParents()
|
||||||
.Select(i => i.PreferredMetadataCountryCode)
|
.Select(i => i.PreferredMetadataCountryCode)
|
||||||
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
|
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
|
||||||
}
|
}
|
||||||
@ -1119,6 +1163,23 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int? GetParentalRatingValue()
|
public int? GetParentalRatingValue()
|
||||||
|
{
|
||||||
|
var rating = CustomRating;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(rating))
|
||||||
|
{
|
||||||
|
rating = OfficialRating;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(rating))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LocalizationManager.GetRatingLevel(rating);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int? GetInheritedParentalRatingValue()
|
||||||
{
|
{
|
||||||
var rating = CustomRatingForComparison;
|
var rating = CustomRatingForComparison;
|
||||||
|
|
||||||
@ -1156,6 +1217,11 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual UnratedItem GetBlockUnratedType()
|
||||||
|
{
|
||||||
|
return UnratedItem.Other;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the block unrated value.
|
/// Gets the block unrated value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1174,7 +1240,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.BlockUnratedItems.Contains(UnratedItem.Other);
|
return config.BlockUnratedItems.Contains(GetBlockUnratedType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1206,14 +1272,14 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Parents.Any(i => !i.IsVisible(user)))
|
if (GetParents().Any(i => !i.IsVisible(user)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkFolders)
|
if (checkFolders)
|
||||||
{
|
{
|
||||||
var topParent = Parents.LastOrDefault() ?? this;
|
var topParent = GetParents().LastOrDefault() ?? this;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(topParent.Path))
|
if (string.IsNullOrWhiteSpace(topParent.Path))
|
||||||
{
|
{
|
||||||
@ -1307,15 +1373,6 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a person to the item
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="person">The person.</param>
|
|
||||||
/// <exception cref="System.ArgumentNullException"></exception>
|
|
||||||
public void AddPerson(PersonInfo person)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a studio to the item
|
/// Adds a studio to the item
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1874,5 +1931,54 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
DateLastSaved.Ticks.ToString(CultureInfo.InvariantCulture)
|
DateLastSaved.Ticks.ToString(CultureInfo.InvariantCulture)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual IEnumerable<Guid> GetAncestorIds()
|
||||||
|
{
|
||||||
|
return GetParents().Select(i => i.Id).Concat(LibraryManager.GetCollectionFolders(this).Select(i => i.Id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseItem GetTopParent()
|
||||||
|
{
|
||||||
|
if (IsTopParent)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetParents().FirstOrDefault(i => i.IsTopParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
|
public virtual bool IsTopParent
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (GetParent() is AggregateFolder || this is Channel || this is BasePluginFolder)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var view = this as UserView;
|
||||||
|
if (view != null && string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
|
public virtual bool SupportsAncestors
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IEnumerable<Guid> GetIdsForAncestorQuery()
|
||||||
|
{
|
||||||
|
return new[] { Id };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -104,6 +104,11 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||||||
.OrderBy(i => i.Name);
|
.OrderBy(i => i.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Guid> GetInstalledChannelIds()
|
||||||
|
{
|
||||||
|
return GetAllChannels().Select(i => GetInternalChannelId(i.Name));
|
||||||
|
}
|
||||||
|
|
||||||
public Task<QueryResult<Channel>> GetChannelsInternal(ChannelQuery query, CancellationToken cancellationToken)
|
public Task<QueryResult<Channel>> GetChannelsInternal(ChannelQuery query, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var user = string.IsNullOrWhiteSpace(query.UserId)
|
var user = string.IsNullOrWhiteSpace(query.UserId)
|
||||||
@ -408,25 +413,15 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||||||
|
|
||||||
private async Task<Channel> GetChannel(IChannel channelInfo, CancellationToken cancellationToken)
|
private async Task<Channel> GetChannel(IChannel channelInfo, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
var parentFolder = await GetInternalChannelFolder(cancellationToken).ConfigureAwait(false);
|
||||||
|
var parentFolderId = parentFolder.Id;
|
||||||
|
|
||||||
var id = GetInternalChannelId(channelInfo.Name);
|
var id = GetInternalChannelId(channelInfo.Name);
|
||||||
|
|
||||||
var path = Channel.GetInternalMetadataPath(_config.ApplicationPaths.InternalMetadataPath, id);
|
var path = Channel.GetInternalMetadataPath(_config.ApplicationPaths.InternalMetadataPath, id);
|
||||||
|
|
||||||
var isNew = false;
|
var isNew = false;
|
||||||
|
var forceUpdate = false;
|
||||||
if (!_fileSystem.DirectoryExists(path))
|
|
||||||
{
|
|
||||||
_logger.Debug("Creating directory {0}", path);
|
|
||||||
|
|
||||||
_fileSystem.CreateDirectory(path);
|
|
||||||
|
|
||||||
if (!_fileSystem.DirectoryExists(path))
|
|
||||||
{
|
|
||||||
throw new IOException("Path not created: " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
isNew = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var item = _libraryManager.GetItemById(id) as Channel;
|
var item = _libraryManager.GetItemById(id) as Channel;
|
||||||
var channelId = channelInfo.Name.GetMD5().ToString("N");
|
var channelId = channelInfo.Name.GetMD5().ToString("N");
|
||||||
@ -438,18 +433,29 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||||||
Name = channelInfo.Name,
|
Name = channelInfo.Name,
|
||||||
Id = id,
|
Id = id,
|
||||||
DateCreated = _fileSystem.GetCreationTimeUtc(path),
|
DateCreated = _fileSystem.GetCreationTimeUtc(path),
|
||||||
DateModified = _fileSystem.GetLastWriteTimeUtc(path),
|
DateModified = _fileSystem.GetLastWriteTimeUtc(path)
|
||||||
Path = path,
|
|
||||||
ChannelId = channelId
|
|
||||||
};
|
};
|
||||||
|
|
||||||
isNew = true;
|
isNew = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.Equals(item.ChannelId, channelId, StringComparison.OrdinalIgnoreCase))
|
if (!string.Equals(item.Path, path, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
isNew = true;
|
isNew = true;
|
||||||
}
|
}
|
||||||
|
item.Path = path;
|
||||||
|
|
||||||
|
if (!string.Equals(item.ChannelId, channelId, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
forceUpdate = true;
|
||||||
|
}
|
||||||
|
item.ChannelId = channelId;
|
||||||
|
|
||||||
|
if (item.ParentId != parentFolderId)
|
||||||
|
{
|
||||||
|
forceUpdate = true;
|
||||||
|
}
|
||||||
|
item.ParentId = parentFolderId;
|
||||||
|
|
||||||
item.OfficialRating = GetOfficialRating(channelInfo.ParentalRating);
|
item.OfficialRating = GetOfficialRating(channelInfo.ParentalRating);
|
||||||
item.Overview = channelInfo.Description;
|
item.Overview = channelInfo.Description;
|
||||||
@ -459,13 +465,17 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||||||
{
|
{
|
||||||
item.Name = channelInfo.Name;
|
item.Name = channelInfo.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
await item.RefreshMetadata(new MetadataRefreshOptions(_fileSystem)
|
if (isNew)
|
||||||
{
|
{
|
||||||
ForceSave = isNew
|
await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}, cancellationToken);
|
else if (forceUpdate)
|
||||||
|
{
|
||||||
|
await item.UpdateToRepository(ItemUpdateType.None, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
await item.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1225,6 +1235,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||||||
{
|
{
|
||||||
BaseItem item;
|
BaseItem item;
|
||||||
bool isNew;
|
bool isNew;
|
||||||
|
bool forceUpdate = false;
|
||||||
|
|
||||||
if (info.Type == ChannelItemType.Folder)
|
if (info.Type == ChannelItemType.Folder)
|
||||||
{
|
{
|
||||||
@ -1254,25 +1265,26 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||||||
item.ProductionYear = info.ProductionYear;
|
item.ProductionYear = info.ProductionYear;
|
||||||
item.ProviderIds = info.ProviderIds;
|
item.ProviderIds = info.ProviderIds;
|
||||||
item.OfficialRating = info.OfficialRating;
|
item.OfficialRating = info.OfficialRating;
|
||||||
|
|
||||||
item.DateCreated = info.DateCreated ?? DateTime.UtcNow;
|
item.DateCreated = info.DateCreated ?? DateTime.UtcNow;
|
||||||
|
item.Tags = info.Tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
var channelItem = (IChannelItem)item;
|
var channelItem = (IChannelItem)item;
|
||||||
|
|
||||||
channelItem.ChannelId = internalChannelId.ToString("N");
|
channelItem.ChannelId = internalChannelId.ToString("N");
|
||||||
|
|
||||||
|
if (item.ParentId != internalChannelId)
|
||||||
|
{
|
||||||
|
forceUpdate = true;
|
||||||
|
}
|
||||||
|
item.ParentId = internalChannelId;
|
||||||
|
|
||||||
if (!string.Equals(channelItem.ExternalId, info.Id, StringComparison.OrdinalIgnoreCase))
|
if (!string.Equals(channelItem.ExternalId, info.Id, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
isNew = true;
|
forceUpdate = true;
|
||||||
}
|
}
|
||||||
channelItem.ExternalId = info.Id;
|
channelItem.ExternalId = info.Id;
|
||||||
|
|
||||||
if (isNew)
|
|
||||||
{
|
|
||||||
channelItem.Tags = info.Tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
var channelMediaItem = item as IChannelMediaItem;
|
var channelMediaItem = item as IChannelMediaItem;
|
||||||
|
|
||||||
if (channelMediaItem != null)
|
if (channelMediaItem != null)
|
||||||
@ -1300,6 +1312,10 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||||||
await _libraryManager.UpdatePeople(item, info.People ?? new List<PersonInfo>()).ConfigureAwait(false);
|
await _libraryManager.UpdatePeople(item, info.People ?? new List<PersonInfo>()).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (forceUpdate)
|
||||||
|
{
|
||||||
|
await item.UpdateToRepository(ItemUpdateType.None, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@ -1573,4 +1589,4 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -534,7 +534,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<LiveTvChannel> GetChannel(ChannelInfo channelInfo, string serviceName, CancellationToken cancellationToken)
|
private async Task<LiveTvChannel> GetChannel(ChannelInfo channelInfo, string serviceName, Guid parentFolderId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var isNew = false;
|
var isNew = false;
|
||||||
|
|
||||||
@ -560,12 +560,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
}
|
}
|
||||||
item.ExternalId = channelInfo.Id;
|
item.ExternalId = channelInfo.Id;
|
||||||
|
|
||||||
|
if (!item.ParentId.Equals(parentFolderId))
|
||||||
|
{
|
||||||
|
isNew = true;
|
||||||
|
}
|
||||||
|
item.ParentId = parentFolderId;
|
||||||
|
|
||||||
item.ChannelType = channelInfo.ChannelType;
|
item.ChannelType = channelInfo.ChannelType;
|
||||||
item.ServiceName = serviceName;
|
item.ServiceName = serviceName;
|
||||||
item.Number = channelInfo.Number;
|
item.Number = channelInfo.Number;
|
||||||
|
|
||||||
var replaceImages = new List<ImageType>();
|
|
||||||
|
|
||||||
//if (!string.Equals(item.ProviderImageUrl, channelInfo.ImageUrl, StringComparison.OrdinalIgnoreCase))
|
//if (!string.Equals(item.ProviderImageUrl, channelInfo.ImageUrl, StringComparison.OrdinalIgnoreCase))
|
||||||
//{
|
//{
|
||||||
// isNew = true;
|
// isNew = true;
|
||||||
@ -577,13 +581,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
// replaceImages.Add(ImageType.Primary);
|
// replaceImages.Add(ImageType.Primary);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(channelInfo.ImagePath))
|
if (!item.HasImage(ImageType.Primary))
|
||||||
{
|
{
|
||||||
item.SetImagePath(ImageType.Primary, channelInfo.ImagePath);
|
if (!string.IsNullOrWhiteSpace(channelInfo.ImagePath))
|
||||||
}
|
{
|
||||||
else if (!string.IsNullOrWhiteSpace(channelInfo.ImageUrl))
|
item.SetImagePath(ImageType.Primary, channelInfo.ImagePath);
|
||||||
{
|
}
|
||||||
item.SetImagePath(ImageType.Primary, channelInfo.ImageUrl);
|
else if (!string.IsNullOrWhiteSpace(channelInfo.ImageUrl))
|
||||||
|
{
|
||||||
|
item.SetImagePath(ImageType.Primary, channelInfo.ImageUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(item.Name))
|
if (string.IsNullOrEmpty(item.Name))
|
||||||
@ -593,20 +600,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
|
|
||||||
await item.RefreshMetadata(new MetadataRefreshOptions(_fileSystem)
|
await item.RefreshMetadata(new MetadataRefreshOptions(_fileSystem)
|
||||||
{
|
{
|
||||||
ForceSave = isNew,
|
ForceSave = isNew
|
||||||
ReplaceImages = replaceImages.Distinct().ToList()
|
|
||||||
|
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<LiveTvProgram> GetProgram(ProgramInfo info, string channelId, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
|
private async Task<LiveTvProgram> GetProgram(ProgramInfo info, LiveTvChannel channel, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var id = _tvDtoService.GetInternalProgramId(serviceName, info.Id);
|
var id = _tvDtoService.GetInternalProgramId(serviceName, info.Id);
|
||||||
|
|
||||||
var item = _libraryManager.GetItemById(id) as LiveTvProgram;
|
var item = _libraryManager.GetItemById(id) as LiveTvProgram;
|
||||||
var isNew = false;
|
var isNew = false;
|
||||||
|
var forceUpdate = false;
|
||||||
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
@ -621,11 +628,21 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
item.ChannelType = channelType;
|
if (!item.ParentId.Equals(channel.Id))
|
||||||
|
{
|
||||||
|
forceUpdate = true;
|
||||||
|
}
|
||||||
|
item.ParentId = channel.Id;
|
||||||
|
|
||||||
|
//item.ChannelType = channelType;
|
||||||
|
if (!string.Equals(item.ServiceName, serviceName, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
forceUpdate = true;
|
||||||
|
}
|
||||||
item.ServiceName = serviceName;
|
item.ServiceName = serviceName;
|
||||||
|
|
||||||
item.Audio = info.Audio;
|
item.Audio = info.Audio;
|
||||||
item.ChannelId = channelId;
|
item.ChannelId = channel.Id.ToString("N");
|
||||||
item.CommunityRating = item.CommunityRating ?? info.CommunityRating;
|
item.CommunityRating = item.CommunityRating ?? info.CommunityRating;
|
||||||
item.EndDate = info.EndDate;
|
item.EndDate = info.EndDate;
|
||||||
item.EpisodeTitle = info.EpisodeTitle;
|
item.EpisodeTitle = info.EpisodeTitle;
|
||||||
@ -674,12 +691,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNew)
|
if (isNew)
|
||||||
{
|
{
|
||||||
await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
|
await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else if (string.IsNullOrWhiteSpace(info.Etag))
|
else if (forceUpdate || string.IsNullOrWhiteSpace(info.Etag))
|
||||||
{
|
{
|
||||||
await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
@ -700,7 +717,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Guid> CreateRecordingRecord(RecordingInfo info, string serviceName, CancellationToken cancellationToken)
|
private async Task<Guid> CreateRecordingRecord(RecordingInfo info, string serviceName, Guid parentFolderId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var isNew = false;
|
var isNew = false;
|
||||||
|
|
||||||
@ -769,13 +786,22 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
}
|
}
|
||||||
recording.IsSeries = info.IsSeries;
|
recording.IsSeries = info.IsSeries;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(info.ImagePath))
|
if (!item.ParentId.Equals(parentFolderId))
|
||||||
{
|
{
|
||||||
item.SetImagePath(ImageType.Primary, info.ImagePath);
|
dataChanged = true;
|
||||||
}
|
}
|
||||||
else if (!string.IsNullOrWhiteSpace(info.ImageUrl))
|
item.ParentId = parentFolderId;
|
||||||
|
|
||||||
|
if (!item.HasImage(ImageType.Primary))
|
||||||
{
|
{
|
||||||
item.SetImagePath(ImageType.Primary, info.ImageUrl);
|
if (!string.IsNullOrWhiteSpace(info.ImagePath))
|
||||||
|
{
|
||||||
|
item.SetImagePath(ImageType.Primary, info.ImagePath);
|
||||||
|
}
|
||||||
|
else if (!string.IsNullOrWhiteSpace(info.ImageUrl))
|
||||||
|
{
|
||||||
|
item.SetImagePath(ImageType.Primary, info.ImageUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var statusChanged = info.Status != recording.Status;
|
var statusChanged = info.Status != recording.Status;
|
||||||
@ -831,14 +857,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
|
|
||||||
var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user);
|
var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user);
|
||||||
|
|
||||||
await AddRecordingInfo(new[] { dto }, cancellationToken).ConfigureAwait(false);
|
var list = new List<Tuple<BaseItemDto, string, string>>();
|
||||||
|
list.Add(new Tuple<BaseItemDto, string, string>(dto, program.ServiceName, program.ExternalId));
|
||||||
|
|
||||||
|
await AddRecordingInfo(list, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<QueryResult<BaseItemDto>> GetPrograms(ProgramQuery query, DtoOptions options, CancellationToken cancellationToken)
|
public async Task<QueryResult<BaseItemDto>> GetPrograms(ProgramQuery query, DtoOptions options, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var internalQuery = new InternalItemsQuery
|
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
|
||||||
|
|
||||||
|
var internalQuery = new InternalItemsQuery(user)
|
||||||
{
|
{
|
||||||
IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
|
IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
|
||||||
MinEndDate = query.MinEndDate,
|
MinEndDate = query.MinEndDate,
|
||||||
@ -856,17 +887,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
SortOrder = query.SortOrder ?? SortOrder.Ascending
|
SortOrder = query.SortOrder ?? SortOrder.Ascending
|
||||||
};
|
};
|
||||||
|
|
||||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
|
|
||||||
if (user != null)
|
|
||||||
{
|
|
||||||
internalQuery.MaxParentalRating = user.Policy.MaxParentalRating;
|
|
||||||
|
|
||||||
if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram))
|
|
||||||
{
|
|
||||||
internalQuery.HasParentalRating = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query.HasAired.HasValue)
|
if (query.HasAired.HasValue)
|
||||||
{
|
{
|
||||||
if (query.HasAired.Value)
|
if (query.HasAired.Value)
|
||||||
@ -882,14 +902,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
var queryResult = _libraryManager.QueryItems(internalQuery);
|
var queryResult = _libraryManager.QueryItems(internalQuery);
|
||||||
|
|
||||||
var returnArray = queryResult.Items
|
var returnArray = queryResult.Items
|
||||||
.Select(i => _dtoService.GetBaseItemDto(i, options, user))
|
.Cast<LiveTvProgram>()
|
||||||
|
.Select(i => new Tuple<BaseItemDto, string, string>(_dtoService.GetBaseItemDto(i, options, user), i.ServiceName, i.ExternalId))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false);
|
await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var result = new QueryResult<BaseItemDto>
|
var result = new QueryResult<BaseItemDto>
|
||||||
{
|
{
|
||||||
Items = returnArray,
|
Items = returnArray.Select(i => i.Item1).ToArray(),
|
||||||
TotalRecordCount = queryResult.TotalRecordCount
|
TotalRecordCount = queryResult.TotalRecordCount
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -898,7 +919,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
|
|
||||||
public async Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken)
|
public async Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var internalQuery = new InternalItemsQuery
|
var user = _userManager.GetUserById(query.UserId);
|
||||||
|
|
||||||
|
var internalQuery = new InternalItemsQuery(user)
|
||||||
{
|
{
|
||||||
IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
|
IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
|
||||||
IsAiring = query.IsAiring,
|
IsAiring = query.IsAiring,
|
||||||
@ -919,17 +942,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = _userManager.GetUserById(query.UserId);
|
|
||||||
if (user != null)
|
|
||||||
{
|
|
||||||
internalQuery.MaxParentalRating = user.Policy.MaxParentalRating;
|
|
||||||
|
|
||||||
if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram))
|
|
||||||
{
|
|
||||||
internalQuery.HasParentalRating = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerable<LiveTvProgram> programs = _libraryManager.QueryItems(internalQuery).Items.Cast<LiveTvProgram>();
|
IEnumerable<LiveTvProgram> programs = _libraryManager.QueryItems(internalQuery).Items.Cast<LiveTvProgram>();
|
||||||
|
|
||||||
var programList = programs.ToList();
|
var programList = programs.ToList();
|
||||||
@ -970,14 +982,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
var user = _userManager.GetUserById(query.UserId);
|
var user = _userManager.GetUserById(query.UserId);
|
||||||
|
|
||||||
var returnArray = internalResult.Items
|
var returnArray = internalResult.Items
|
||||||
.Select(i => _dtoService.GetBaseItemDto(i, options, user))
|
.Select(i => new Tuple<BaseItemDto, string, string>(_dtoService.GetBaseItemDto(i, options, user), i.ServiceName, i.ExternalId))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false);
|
await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var result = new QueryResult<BaseItemDto>
|
var result = new QueryResult<BaseItemDto>
|
||||||
{
|
{
|
||||||
Items = returnArray,
|
Items = returnArray.Select(i => i.Item1).ToArray(),
|
||||||
TotalRecordCount = internalResult.TotalRecordCount
|
TotalRecordCount = internalResult.TotalRecordCount
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1053,40 +1065,46 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
}).Sum();
|
}).Sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task AddRecordingInfo(IEnumerable<BaseItemDto> programs, CancellationToken cancellationToken)
|
private async Task AddRecordingInfo(IEnumerable<Tuple<BaseItemDto, string, string>> programs, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var timers = new Dictionary<string, List<TimerInfo>>();
|
var timers = new Dictionary<string, List<TimerInfo>>();
|
||||||
|
|
||||||
foreach (var program in programs)
|
foreach (var programTuple in programs)
|
||||||
{
|
{
|
||||||
var internalProgram = GetInternalProgram(program.Id);
|
var program = programTuple.Item1;
|
||||||
|
var serviceName = programTuple.Item2;
|
||||||
|
var externalProgramId = programTuple.Item3;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(serviceName))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
List<TimerInfo> timerList;
|
List<TimerInfo> timerList;
|
||||||
if (!timers.TryGetValue(internalProgram.ServiceName, out timerList))
|
if (!timers.TryGetValue(serviceName, out timerList))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var tempTimers = await GetService(internalProgram.ServiceName).GetTimersAsync(cancellationToken).ConfigureAwait(false);
|
var tempTimers = await GetService(serviceName).GetTimersAsync(cancellationToken).ConfigureAwait(false);
|
||||||
timers[internalProgram.ServiceName] = timerList = tempTimers.ToList();
|
timers[serviceName] = timerList = tempTimers.ToList();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error getting timer infos", ex);
|
_logger.ErrorException("Error getting timer infos", ex);
|
||||||
timers[internalProgram.ServiceName] = timerList = new List<TimerInfo>();
|
timers[serviceName] = timerList = new List<TimerInfo>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var timer = timerList.FirstOrDefault(i => string.Equals(i.ProgramId, externalProgramId, StringComparison.OrdinalIgnoreCase));
|
||||||
var timer = timerList.FirstOrDefault(i => string.Equals(i.ProgramId, internalProgram.ExternalId, StringComparison.OrdinalIgnoreCase));
|
|
||||||
|
|
||||||
if (timer != null)
|
if (timer != null)
|
||||||
{
|
{
|
||||||
program.TimerId = _tvDtoService.GetInternalTimerId(internalProgram.ServiceName, timer.Id)
|
program.TimerId = _tvDtoService.GetInternalTimerId(serviceName, timer.Id)
|
||||||
.ToString("N");
|
.ToString("N");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(timer.SeriesTimerId))
|
if (!string.IsNullOrEmpty(timer.SeriesTimerId))
|
||||||
{
|
{
|
||||||
program.SeriesTimerId = _tvDtoService.GetInternalSeriesTimerId(internalProgram.ServiceName, timer.SeriesTimerId)
|
program.SeriesTimerId = _tvDtoService.GetInternalSeriesTimerId(serviceName, timer.SeriesTimerId)
|
||||||
.ToString("N");
|
.ToString("N");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1168,6 +1186,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
var list = new List<LiveTvChannel>();
|
var list = new List<LiveTvChannel>();
|
||||||
|
|
||||||
var numComplete = 0;
|
var numComplete = 0;
|
||||||
|
var parentFolder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false);
|
||||||
|
var parentFolderId = parentFolder.Id;
|
||||||
|
|
||||||
foreach (var channelInfo in allChannelsList)
|
foreach (var channelInfo in allChannelsList)
|
||||||
{
|
{
|
||||||
@ -1175,7 +1195,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var item = await GetChannel(channelInfo.Item2, channelInfo.Item1, cancellationToken).ConfigureAwait(false);
|
var item = await GetChannel(channelInfo.Item2, channelInfo.Item1, parentFolderId, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
list.Add(item);
|
list.Add(item);
|
||||||
|
|
||||||
@ -1205,6 +1225,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
|
|
||||||
var guideDays = GetGuideDays(list.Count);
|
var guideDays = GetGuideDays(list.Count);
|
||||||
|
|
||||||
|
_logger.Info("Refreshing guide with {0} days of guide data", guideDays);
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
foreach (var currentChannel in list)
|
foreach (var currentChannel in list)
|
||||||
@ -1219,11 +1241,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
|
|
||||||
var channelPrograms = await service.GetProgramsAsync(currentChannel.ExternalId, start, end, cancellationToken).ConfigureAwait(false);
|
var channelPrograms = await service.GetProgramsAsync(currentChannel.ExternalId, start, end, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var channelId = currentChannel.Id.ToString("N");
|
|
||||||
|
|
||||||
foreach (var program in channelPrograms)
|
foreach (var program in channelPrograms)
|
||||||
{
|
{
|
||||||
var programItem = await GetProgram(program, channelId, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false);
|
var programItem = await GetProgram(program, currentChannel, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
programs.Add(programItem.Id);
|
programs.Add(programItem.Id);
|
||||||
}
|
}
|
||||||
@ -1290,13 +1310,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const int MaxGuideDays = 14;
|
||||||
private double GetGuideDays(int channelCount)
|
private double GetGuideDays(int channelCount)
|
||||||
{
|
{
|
||||||
var config = GetConfiguration();
|
var config = GetConfiguration();
|
||||||
|
|
||||||
if (config.GuideDays.HasValue)
|
if (config.GuideDays.HasValue)
|
||||||
{
|
{
|
||||||
return config.GuideDays.Value;
|
return Math.Max(1, Math.Min(config.GuideDays.Value, MaxGuideDays));
|
||||||
}
|
}
|
||||||
|
|
||||||
var programsPerDay = channelCount * 48;
|
var programsPerDay = channelCount * 48;
|
||||||
@ -1305,7 +1326,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
|
|
||||||
var days = Math.Round(((double)maxPrograms) / programsPerDay);
|
var days = Math.Round(((double)maxPrograms) / programsPerDay);
|
||||||
|
|
||||||
return Math.Max(3, Math.Min(days, 14));
|
return Math.Max(3, Math.Min(days, MaxGuideDays));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<Tuple<string, ChannelInfo>>> GetChannels(ILiveTvService service, CancellationToken cancellationToken)
|
private async Task<IEnumerable<Tuple<string, ChannelInfo>>> GetChannels(ILiveTvService service, CancellationToken cancellationToken)
|
||||||
@ -1349,8 +1370,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
});
|
});
|
||||||
|
|
||||||
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
|
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||||
|
var folder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false);
|
||||||
|
var parentFolderId = folder.Id;
|
||||||
|
|
||||||
var recordingTasks = results.SelectMany(i => i.ToList()).Select(i => CreateRecordingRecord(i.Item1, i.Item2.Name, cancellationToken));
|
var recordingTasks = results.SelectMany(i => i.ToList()).Select(i => CreateRecordingRecord(i.Item1, i.Item2.Name, parentFolderId, cancellationToken));
|
||||||
|
|
||||||
var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false);
|
var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false);
|
||||||
|
|
||||||
@ -1374,7 +1397,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
|
|
||||||
await RefreshRecordings(cancellationToken).ConfigureAwait(false);
|
await RefreshRecordings(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var internalQuery = new InternalItemsQuery
|
var internalQuery = new InternalItemsQuery(user)
|
||||||
{
|
{
|
||||||
IncludeItemTypes = new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }
|
IncludeItemTypes = new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }
|
||||||
};
|
};
|
||||||
@ -1384,8 +1407,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
internalQuery.ChannelIds = new[] { query.ChannelId };
|
internalQuery.ChannelIds = new[] { query.ChannelId };
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryResult = _libraryManager.GetItems(internalQuery);
|
var queryResult = _libraryManager.GetItems(internalQuery, new string[] { });
|
||||||
IEnumerable<ILiveTvRecording> recordings = queryResult.Items.Cast<ILiveTvRecording>();
|
IEnumerable<ILiveTvRecording> recordings = queryResult.Cast<ILiveTvRecording>();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(query.Id))
|
if (!string.IsNullOrEmpty(query.Id))
|
||||||
{
|
{
|
||||||
@ -1422,12 +1445,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
.Where(i => _tvDtoService.GetInternalSeriesTimerId(i.ServiceName, i.SeriesTimerId) == guid);
|
.Where(i => _tvDtoService.GetInternalSeriesTimerId(i.ServiceName, i.SeriesTimerId) == guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user != null)
|
|
||||||
{
|
|
||||||
var currentUser = user;
|
|
||||||
recordings = recordings.Where(i => i.IsParentalAllowed(currentUser));
|
|
||||||
}
|
|
||||||
|
|
||||||
recordings = recordings.OrderByDescending(i => i.StartDate);
|
recordings = recordings.OrderByDescending(i => i.StartDate);
|
||||||
|
|
||||||
var entityList = recordings.ToList();
|
var entityList = recordings.ToList();
|
||||||
@ -1453,18 +1470,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
public void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, bool addChannelInfo, User user = null)
|
public void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, bool addChannelInfo, User user = null)
|
||||||
{
|
{
|
||||||
var program = (LiveTvProgram)item;
|
var program = (LiveTvProgram)item;
|
||||||
var service = GetService(program);
|
|
||||||
|
|
||||||
dto.Id = _tvDtoService.GetInternalProgramId(service.Name, program.ExternalId).ToString("N");
|
|
||||||
|
|
||||||
dto.StartDate = program.StartDate;
|
dto.StartDate = program.StartDate;
|
||||||
dto.EpisodeTitle = program.EpisodeTitle;
|
dto.EpisodeTitle = program.EpisodeTitle;
|
||||||
dto.Audio = program.Audio;
|
|
||||||
|
|
||||||
if (program.IsHD.HasValue && program.IsHD.Value)
|
|
||||||
{
|
|
||||||
dto.IsHD = program.IsHD;
|
|
||||||
}
|
|
||||||
if (program.IsRepeat)
|
if (program.IsRepeat)
|
||||||
{
|
{
|
||||||
dto.IsRepeat = program.IsRepeat;
|
dto.IsRepeat = program.IsRepeat;
|
||||||
@ -1523,7 +1532,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
|
|
||||||
var info = recording;
|
var info = recording;
|
||||||
|
|
||||||
dto.Id = item.Id.ToString("N");
|
|
||||||
dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId)
|
dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId)
|
||||||
? null
|
? null
|
||||||
: _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N");
|
: _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N");
|
||||||
@ -1532,8 +1540,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
dto.RecordingStatus = info.Status;
|
dto.RecordingStatus = info.Status;
|
||||||
dto.IsRepeat = info.IsRepeat;
|
dto.IsRepeat = info.IsRepeat;
|
||||||
dto.EpisodeTitle = info.EpisodeTitle;
|
dto.EpisodeTitle = info.EpisodeTitle;
|
||||||
dto.Audio = info.Audio;
|
|
||||||
dto.IsHD = info.IsHD;
|
|
||||||
dto.IsMovie = info.IsMovie;
|
dto.IsMovie = info.IsMovie;
|
||||||
dto.IsSeries = info.IsSeries;
|
dto.IsSeries = info.IsSeries;
|
||||||
dto.IsSports = info.IsSports;
|
dto.IsSports = info.IsSports;
|
||||||
@ -1804,19 +1810,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
var programs = _libraryManager.GetItems(new InternalItemsQuery
|
var programs = _libraryManager.GetItems(new InternalItemsQuery(user)
|
||||||
{
|
{
|
||||||
IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
|
IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
|
||||||
ChannelIds = new[] { id },
|
ChannelIds = new[] { id },
|
||||||
MaxStartDate = now,
|
MaxStartDate = now,
|
||||||
MinEndDate = now,
|
MinEndDate = now,
|
||||||
Limit = 1
|
Limit = 1,
|
||||||
|
SortBy = new[] { "StartDate" }
|
||||||
|
|
||||||
}).Items.Cast<LiveTvProgram>();
|
}, new string[] { }).Cast<LiveTvProgram>();
|
||||||
|
|
||||||
var currentProgram = programs
|
var currentProgram = programs.FirstOrDefault();
|
||||||
.OrderBy(i => i.StartDate)
|
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
var dto = _tvDtoService.GetChannelInfoDto(channel, new DtoOptions(), currentProgram, user);
|
var dto = _tvDtoService.GetChannelInfoDto(channel, new DtoOptions(), currentProgram, user);
|
||||||
|
|
||||||
@ -1829,19 +1834,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
var programs = _libraryManager.GetItems(new InternalItemsQuery
|
var programs = _libraryManager.GetItems(new InternalItemsQuery(user)
|
||||||
{
|
{
|
||||||
IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
|
IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
|
||||||
ChannelIds = new[] { channel.Id.ToString("N") },
|
ChannelIds = new[] { channel.Id.ToString("N") },
|
||||||
MaxStartDate = now,
|
MaxStartDate = now,
|
||||||
MinEndDate = now,
|
MinEndDate = now,
|
||||||
Limit = 1
|
Limit = 1,
|
||||||
|
SortBy = new[] { "StartDate" }
|
||||||
|
|
||||||
}).Items.Cast<LiveTvProgram>();
|
}, new string[] { }).Cast<LiveTvProgram>();
|
||||||
|
|
||||||
var currentProgram = programs
|
var currentProgram = programs.FirstOrDefault();
|
||||||
.OrderBy(i => i.StartDate)
|
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
if (currentProgram != null)
|
if (currentProgram != null)
|
||||||
{
|
{
|
||||||
@ -2302,7 +2306,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||||||
public async Task<Folder> GetInternalLiveTvFolder(CancellationToken cancellationToken)
|
public async Task<Folder> GetInternalLiveTvFolder(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var name = _localization.GetLocalizedString("ViewTypeLiveTV");
|
var name = _localization.GetLocalizedString("ViewTypeLiveTV");
|
||||||
return await _libraryManager.GetNamedView(name, "livetv", name, cancellationToken).ConfigureAwait(false);
|
return await _libraryManager.GetNamedView(name, CollectionType.LiveTv, name, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info)
|
public async Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user