commit
dbf1e2c27e
|
@ -835,14 +835,14 @@ namespace MediaBrowser.Api.Library
|
||||||
: (Folder)_libraryManager.RootFolder)
|
: (Folder)_libraryManager.RootFolder)
|
||||||
: _libraryManager.GetItemById(request.Id);
|
: _libraryManager.GetItemById(request.Id);
|
||||||
|
|
||||||
while (GetThemeSongIds(item).Count == 0 && request.InheritFromParent && item.GetParent() != null)
|
while (item.ThemeSongIds.Count == 0 && request.InheritFromParent && item.GetParent() != null)
|
||||||
{
|
{
|
||||||
item = item.GetParent();
|
item = item.GetParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtoOptions = GetDtoOptions(request);
|
var dtoOptions = GetDtoOptions(request);
|
||||||
|
|
||||||
var dtos = GetThemeSongIds(item).Select(_libraryManager.GetItemById)
|
var dtos = item.ThemeSongIds.Select(_libraryManager.GetItemById)
|
||||||
.Where(i => i != null)
|
.Where(i => i != null)
|
||||||
.OrderBy(i => i.SortName)
|
.OrderBy(i => i.SortName)
|
||||||
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
|
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
|
||||||
|
@ -879,14 +879,14 @@ namespace MediaBrowser.Api.Library
|
||||||
: (Folder)_libraryManager.RootFolder)
|
: (Folder)_libraryManager.RootFolder)
|
||||||
: _libraryManager.GetItemById(request.Id);
|
: _libraryManager.GetItemById(request.Id);
|
||||||
|
|
||||||
while (GetThemeVideoIds(item).Count == 0 && request.InheritFromParent && item.GetParent() != null)
|
while (item.ThemeVideoIds.Count == 0 && request.InheritFromParent && item.GetParent() != null)
|
||||||
{
|
{
|
||||||
item = item.GetParent();
|
item = item.GetParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtoOptions = GetDtoOptions(request);
|
var dtoOptions = GetDtoOptions(request);
|
||||||
|
|
||||||
var dtos = GetThemeVideoIds(item).Select(_libraryManager.GetItemById)
|
var dtos = item.ThemeVideoIds.Select(_libraryManager.GetItemById)
|
||||||
.Where(i => i != null)
|
.Where(i => i != null)
|
||||||
.OrderBy(i => i.SortName)
|
.OrderBy(i => i.SortName)
|
||||||
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
|
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
|
||||||
|
@ -901,30 +901,6 @@ namespace MediaBrowser.Api.Library
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Guid> GetThemeVideoIds(BaseItem item)
|
|
||||||
{
|
|
||||||
var i = item as IHasThemeMedia;
|
|
||||||
|
|
||||||
if (i != null)
|
|
||||||
{
|
|
||||||
return i.ThemeVideoIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new List<Guid>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Guid> GetThemeSongIds(BaseItem item)
|
|
||||||
{
|
|
||||||
var i = item as IHasThemeMedia;
|
|
||||||
|
|
||||||
if (i != null)
|
|
||||||
{
|
|
||||||
return i.ThemeSongIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new List<Guid>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||||
|
|
||||||
public object Get(GetYearIndex request)
|
public object Get(GetYearIndex request)
|
||||||
|
|
|
@ -677,6 +677,12 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
public string Container { get; set; }
|
public string Container { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Route("/LiveTv/LiveRecordings/{Id}/stream", "GET", Summary = "Gets a live tv channel")]
|
||||||
|
public class GetLiveRecordingFile
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class LiveTvService : BaseApiService
|
public class LiveTvService : BaseApiService
|
||||||
{
|
{
|
||||||
private readonly ILiveTvManager _liveTvManager;
|
private readonly ILiveTvManager _liveTvManager;
|
||||||
|
@ -698,13 +704,32 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<object> Get(GetLiveRecordingFile request)
|
||||||
|
{
|
||||||
|
var path = EmbyTV.Current.GetActiveRecordingPath(request.Id);
|
||||||
|
|
||||||
|
if (path == null)
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType(path);
|
||||||
|
|
||||||
|
var streamSource = new ProgressiveFileCopier(_fileSystem, path, outputHeaders, null, Logger, CancellationToken.None)
|
||||||
|
{
|
||||||
|
AllowEndOfFile = false
|
||||||
|
};
|
||||||
|
return ResultFactory.GetAsyncStreamWriter(streamSource);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<object> Get(GetLiveStreamFile request)
|
public async Task<object> Get(GetLiveStreamFile request)
|
||||||
{
|
{
|
||||||
var directStreamProvider = (await EmbyTV.Current.GetLiveStream(request.Id).ConfigureAwait(false)) as IDirectStreamProvider;
|
var directStreamProvider = (await EmbyTV.Current.GetLiveStream(request.Id).ConfigureAwait(false)) as IDirectStreamProvider;
|
||||||
var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
// TODO: Don't hardcode this
|
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType("file." + request.Container);
|
||||||
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType("file.ts");
|
|
||||||
|
|
||||||
var streamSource = new ProgressiveFileCopier(directStreamProvider, outputHeaders, null, Logger, CancellationToken.None)
|
var streamSource = new ProgressiveFileCopier(directStreamProvider, outputHeaders, null, Logger, CancellationToken.None)
|
||||||
{
|
{
|
||||||
|
|
|
@ -134,15 +134,5 @@ namespace MediaBrowser.Controller.Channels
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>BaseItemDto.</returns>
|
/// <returns>BaseItemDto.</returns>
|
||||||
Task<BaseItemDto> GetChannelFolder(string userId, CancellationToken cancellationToken);
|
Task<BaseItemDto> GetChannelFolder(string userId, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Downloads the channel item.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item">The item.</param>
|
|
||||||
/// <param name="destinationPath">The destination path.</param>
|
|
||||||
/// <param name="progress">The progress.</param>
|
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
|
||||||
/// <returns>Task.</returns>
|
|
||||||
Task DownloadChannelItem(BaseItem item, string destinationPath, IProgress<double> progress, CancellationToken cancellationToken);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,12 @@ namespace MediaBrowser.Controller.Entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
|
public override bool IsPhysicalRoot
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
public override bool CanDelete()
|
public override bool CanDelete()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -62,7 +62,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public override bool SupportsAddingToPlaylist
|
public override bool SupportsAddingToPlaylist
|
||||||
{
|
{
|
||||||
get { return LocationType == LocationType.FileSystem && RunTimeTicks.HasValue; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
|
|
|
@ -37,6 +37,8 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
protected BaseItem()
|
protected BaseItem()
|
||||||
{
|
{
|
||||||
|
ThemeSongIds = new List<Guid>();
|
||||||
|
ThemeVideoIds = new List<Guid>();
|
||||||
Keywords = new List<string>();
|
Keywords = new List<string>();
|
||||||
Tags = new List<string>();
|
Tags = new List<string>();
|
||||||
Genres = new List<string>();
|
Genres = new List<string>();
|
||||||
|
@ -45,6 +47,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
LockedFields = new List<MetadataFields>();
|
LockedFields = new List<MetadataFields>();
|
||||||
ImageInfos = new List<ItemImageInfo>();
|
ImageInfos = new List<ItemImageInfo>();
|
||||||
InheritedTags = new List<string>();
|
InheritedTags = new List<string>();
|
||||||
|
ProductionLocations = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly char[] SlugReplaceChars = { '?', '/', '&' };
|
public static readonly char[] SlugReplaceChars = { '?', '/', '&' };
|
||||||
|
@ -65,6 +68,9 @@ namespace MediaBrowser.Controller.Entities
|
||||||
public static string ThemeSongFilename = "theme";
|
public static string ThemeSongFilename = "theme";
|
||||||
public static string ThemeVideosFolderName = "backdrops";
|
public static string ThemeVideosFolderName = "backdrops";
|
||||||
|
|
||||||
|
public List<Guid> ThemeSongIds { get; set; }
|
||||||
|
public List<Guid> ThemeVideoIds { get; set; }
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public string PreferredMetadataCountryCode { get; set; }
|
public string PreferredMetadataCountryCode { get; set; }
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
|
@ -876,6 +882,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
public List<string> Tags { get; set; }
|
public List<string> Tags { get; set; }
|
||||||
|
|
||||||
public List<string> Keywords { get; set; }
|
public List<string> Keywords { get; set; }
|
||||||
|
public List<string> ProductionLocations { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the home page URL.
|
/// Gets or sets the home page URL.
|
||||||
|
@ -991,7 +998,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// Loads the theme songs.
|
/// Loads the theme songs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>List{Audio.Audio}.</returns>
|
/// <returns>List{Audio.Audio}.</returns>
|
||||||
private IEnumerable<Audio.Audio> LoadThemeSongs(List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
|
private static IEnumerable<Audio.Audio> LoadThemeSongs(List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var files = fileSystemChildren.Where(i => i.IsDirectory)
|
var files = fileSystemChildren.Where(i => i.IsDirectory)
|
||||||
.Where(i => string.Equals(i.Name, ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase))
|
.Where(i => string.Equals(i.Name, ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase))
|
||||||
|
@ -1027,7 +1034,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// Loads the video backdrops.
|
/// Loads the video backdrops.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>List{Video}.</returns>
|
/// <returns>List{Video}.</returns>
|
||||||
private IEnumerable<Video> LoadThemeVideos(IEnumerable<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
|
private static IEnumerable<Video> LoadThemeVideos(IEnumerable<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var files = fileSystemChildren.Where(i => i.IsDirectory)
|
var files = fileSystemChildren.Where(i => i.IsDirectory)
|
||||||
.Where(i => string.Equals(i.Name, ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase))
|
.Where(i => string.Equals(i.Name, ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase))
|
||||||
|
@ -1113,6 +1120,12 @@ namespace MediaBrowser.Controller.Entities
|
||||||
get { return true; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
|
public virtual bool SupportsThemeMedia
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Refreshes owned items such as trailers, theme videos, special features, etc.
|
/// Refreshes owned items such as trailers, theme videos, special features, etc.
|
||||||
/// Returns true or false indicating if changes were found.
|
/// Returns true or false indicating if changes were found.
|
||||||
|
@ -1131,14 +1144,13 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
if (LocationType == LocationType.FileSystem && GetParent() != null)
|
if (LocationType == LocationType.FileSystem && GetParent() != null)
|
||||||
{
|
{
|
||||||
var hasThemeMedia = this as IHasThemeMedia;
|
if (SupportsThemeMedia)
|
||||||
if (hasThemeMedia != null)
|
|
||||||
{
|
{
|
||||||
if (!DetectIsInMixedFolder())
|
if (!DetectIsInMixedFolder())
|
||||||
{
|
{
|
||||||
themeSongsChanged = await RefreshThemeSongs(hasThemeMedia, options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
|
themeSongsChanged = await RefreshThemeSongs(this, options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
themeVideosChanged = await RefreshThemeVideos(hasThemeMedia, options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
|
themeVideosChanged = await RefreshThemeVideos(this, options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1176,7 +1188,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return itemsChanged;
|
return itemsChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> RefreshThemeVideos(IHasThemeMedia item, MetadataRefreshOptions options, IEnumerable<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
|
private static async Task<bool> RefreshThemeVideos(BaseItem item, MetadataRefreshOptions options, IEnumerable<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var newThemeVideos = LoadThemeVideos(fileSystemChildren, options.DirectoryService).ToList();
|
var newThemeVideos = LoadThemeVideos(fileSystemChildren, options.DirectoryService).ToList();
|
||||||
|
|
||||||
|
@ -1207,7 +1219,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Refreshes the theme songs.
|
/// Refreshes the theme songs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task<bool> RefreshThemeSongs(IHasThemeMedia item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
|
private static async Task<bool> RefreshThemeSongs(BaseItem item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var newThemeSongs = LoadThemeSongs(fileSystemChildren, options.DirectoryService).ToList();
|
var newThemeSongs = LoadThemeSongs(fileSystemChildren, options.DirectoryService).ToList();
|
||||||
var newThemeSongIds = newThemeSongs.Select(i => i.Id).ToList();
|
var newThemeSongIds = newThemeSongs.Select(i => i.Id).ToList();
|
||||||
|
|
|
@ -22,13 +22,18 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class Folder
|
/// Class Folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Folder : BaseItem, IHasThemeMedia
|
public class Folder : BaseItem
|
||||||
{
|
{
|
||||||
public static IUserManager UserManager { get; set; }
|
public static IUserManager UserManager { get; set; }
|
||||||
public static IUserViewManager UserViewManager { get; set; }
|
public static IUserViewManager UserViewManager { get; set; }
|
||||||
|
|
||||||
public List<Guid> ThemeSongIds { get; set; }
|
/// <summary>
|
||||||
public List<Guid> ThemeVideoIds { get; set; }
|
/// Gets or sets a value indicating whether this instance is root.
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>true</c> if this instance is root; otherwise, <c>false</c>.</value>
|
||||||
|
public bool IsRoot { get; set; }
|
||||||
|
|
||||||
|
public virtual List<LinkedChild> LinkedChildren { get; set; }
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public DateTime? DateLastMediaAdded { get; set; }
|
public DateTime? DateLastMediaAdded { get; set; }
|
||||||
|
@ -36,9 +41,12 @@ namespace MediaBrowser.Controller.Entities
|
||||||
public Folder()
|
public Folder()
|
||||||
{
|
{
|
||||||
LinkedChildren = new List<LinkedChild>();
|
LinkedChildren = new List<LinkedChild>();
|
||||||
|
}
|
||||||
|
|
||||||
ThemeSongIds = new List<Guid>();
|
[IgnoreDataMember]
|
||||||
ThemeVideoIds = new List<Guid>();
|
public override bool SupportsThemeMedia
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
|
@ -47,6 +55,12 @@ namespace MediaBrowser.Controller.Entities
|
||||||
get { return false; }
|
get { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
|
public virtual bool IsPhysicalRoot
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this instance is folder.
|
/// Gets a value indicating whether this instance is folder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -117,19 +131,6 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is physical root.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is physical root; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsPhysicalRoot { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is root.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is root; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsRoot { get; set; }
|
|
||||||
|
|
||||||
public virtual List<LinkedChild> LinkedChildren { get; set; }
|
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
protected virtual bool SupportsShortcutChildren
|
protected virtual bool SupportsShortcutChildren
|
||||||
{
|
{
|
||||||
|
@ -178,8 +179,6 @@ namespace MediaBrowser.Controller.Entities
|
||||||
item.SetParent(null);
|
item.SetParent(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Indexing
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the valid set of index by options for this folder type.
|
/// Returns the valid set of index by options for this folder type.
|
||||||
/// Override or extend to modify.
|
/// Override or extend to modify.
|
||||||
|
@ -207,8 +206,6 @@ namespace MediaBrowser.Controller.Entities
|
||||||
get { return GetIndexByOptions(); }
|
get { return GetIndexByOptions(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the actual children.
|
/// Gets the actual children.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -8,11 +8,8 @@ using System.Runtime.Serialization;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Entities
|
namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
public class Game : BaseItem, IHasTrailers, IHasThemeMedia, IHasScreenshots, ISupportsPlaceHolders, IHasLookupInfo<GameInfo>
|
public class Game : BaseItem, IHasTrailers, IHasScreenshots, ISupportsPlaceHolders, IHasLookupInfo<GameInfo>
|
||||||
{
|
{
|
||||||
public List<Guid> ThemeSongIds { get; set; }
|
|
||||||
public List<Guid> ThemeVideoIds { get; set; }
|
|
||||||
|
|
||||||
public Game()
|
public Game()
|
||||||
{
|
{
|
||||||
MultiPartGameFiles = new List<string>();
|
MultiPartGameFiles = new List<string>();
|
||||||
|
@ -39,6 +36,12 @@ namespace MediaBrowser.Controller.Entities
|
||||||
get { return true; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
|
public override bool SupportsThemeMedia
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the remote trailers.
|
/// Gets or sets the remote trailers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Entities
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Interface IHasThemeMedia
|
|
||||||
/// </summary>
|
|
||||||
public interface IHasThemeMedia
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the theme song ids.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The theme song ids.</value>
|
|
||||||
List<Guid> ThemeSongIds { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the theme video ids.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The theme video ids.</value>
|
|
||||||
List<Guid> ThemeVideoIds { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -165,6 +165,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
switch (name)
|
switch (name)
|
||||||
{
|
{
|
||||||
|
case ItemFields.ProductionLocations:
|
||||||
case ItemFields.Keywords:
|
case ItemFields.Keywords:
|
||||||
case ItemFields.Taglines:
|
case ItemFields.Taglines:
|
||||||
case ItemFields.ShortOverview:
|
case ItemFields.ShortOverview:
|
||||||
|
|
|
@ -15,21 +15,16 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class Movie
|
/// Class Movie
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasBudget, IHasTrailers, IHasThemeMedia, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping, IHasOriginalTitle
|
public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasBudget, IHasTrailers, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping, IHasOriginalTitle
|
||||||
{
|
{
|
||||||
public List<Guid> SpecialFeatureIds { get; set; }
|
public List<Guid> SpecialFeatureIds { get; set; }
|
||||||
|
|
||||||
public List<Guid> ThemeSongIds { get; set; }
|
|
||||||
public List<Guid> ThemeVideoIds { get; set; }
|
|
||||||
|
|
||||||
public Movie()
|
public Movie()
|
||||||
{
|
{
|
||||||
SpecialFeatureIds = new List<Guid>();
|
SpecialFeatureIds = new List<Guid>();
|
||||||
RemoteTrailers = new List<MediaUrl>();
|
RemoteTrailers = new List<MediaUrl>();
|
||||||
LocalTrailerIds = new List<Guid>();
|
LocalTrailerIds = new List<Guid>();
|
||||||
RemoteTrailerIds = new List<Guid>();
|
RemoteTrailerIds = new List<Guid>();
|
||||||
ThemeSongIds = new List<Guid>();
|
|
||||||
ThemeVideoIds = new List<Guid>();
|
|
||||||
Taglines = new List<string>();
|
Taglines = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,8 +154,6 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
|
|
||||||
Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
|
Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
|
||||||
|
|
||||||
var id = Guid.NewGuid().ToString("N");
|
|
||||||
|
|
||||||
var items = GetEpisodes(user).Where(filter);
|
var items = GetEpisodes(user).Where(filter);
|
||||||
|
|
||||||
var result = PostFilterAndSort(items, query, false, false);
|
var result = PostFilterAndSort(items, query, false, false);
|
||||||
|
|
|
@ -13,7 +13,6 @@ namespace MediaBrowser.Controller.Entities
|
||||||
public class UserView : Folder
|
public class UserView : Folder
|
||||||
{
|
{
|
||||||
public string ViewType { get; set; }
|
public string ViewType { get; set; }
|
||||||
public Guid ParentId { get; set; }
|
|
||||||
public Guid DisplayParentId { get; set; }
|
public Guid DisplayParentId { get; set; }
|
||||||
|
|
||||||
public Guid? UserId { get; set; }
|
public Guid? UserId { get; set; }
|
||||||
|
|
|
@ -1497,13 +1497,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
var filterValue = query.HasThemeSong.Value;
|
var filterValue = query.HasThemeSong.Value;
|
||||||
|
|
||||||
var themeCount = 0;
|
var themeCount = item.ThemeSongIds.Count;
|
||||||
var iHasThemeMedia = item as IHasThemeMedia;
|
|
||||||
|
|
||||||
if (iHasThemeMedia != null)
|
|
||||||
{
|
|
||||||
themeCount = iHasThemeMedia.ThemeSongIds.Count;
|
|
||||||
}
|
|
||||||
var ok = filterValue ? themeCount > 0 : themeCount == 0;
|
var ok = filterValue ? themeCount > 0 : themeCount == 0;
|
||||||
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
|
@ -1516,13 +1510,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
var filterValue = query.HasThemeVideo.Value;
|
var filterValue = query.HasThemeVideo.Value;
|
||||||
|
|
||||||
var themeCount = 0;
|
var themeCount = item.ThemeVideoIds.Count;
|
||||||
var iHasThemeMedia = item as IHasThemeMedia;
|
|
||||||
|
|
||||||
if (iHasThemeMedia != null)
|
|
||||||
{
|
|
||||||
themeCount = iHasThemeMedia.ThemeVideoIds.Count;
|
|
||||||
}
|
|
||||||
var ok = filterValue ? themeCount > 0 : themeCount == 0;
|
var ok = filterValue ? themeCount > 0 : themeCount == 0;
|
||||||
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
|
|
|
@ -63,6 +63,12 @@ namespace MediaBrowser.Controller.Entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
|
public override bool SupportsThemeMedia
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
public int? TotalBitrate { get; set; }
|
public int? TotalBitrate { get; set; }
|
||||||
public ExtraType? ExtraType { get; set; }
|
public ExtraType? ExtraType { get; set; }
|
||||||
|
|
||||||
|
@ -164,7 +170,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public override bool SupportsAddingToPlaylist
|
public override bool SupportsAddingToPlaylist
|
||||||
{
|
{
|
||||||
get { return LocationType == LocationType.FileSystem && RunTimeTicks.HasValue; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
|
|
|
@ -301,18 +301,12 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the recording media sources.
|
/// Gets the recording media sources.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">The identifier.</param>
|
Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(IHasMediaSources item, CancellationToken cancellationToken);
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
|
||||||
/// <returns>Task<IEnumerable<MediaSourceInfo>>.</returns>
|
|
||||||
Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(string id, CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the channel media sources.
|
/// Gets the channel media sources.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">The identifier.</param>
|
Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(IHasMediaSources item, CancellationToken cancellationToken);
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
|
||||||
/// <returns>Task<IEnumerable<MediaSourceInfo>>.</returns>
|
|
||||||
Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(string id, CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the information to recording dto.
|
/// Adds the information to recording dto.
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
bool CanDelete(User user);
|
bool CanDelete(User user);
|
||||||
|
|
||||||
string SeriesTimerId { get; set; }
|
string SeriesTimerId { get; set; }
|
||||||
|
string TimerId { get; set; }
|
||||||
RecordingStatus Status { get; set; }
|
RecordingStatus Status { get; set; }
|
||||||
DateTime? EndDate { get; set; }
|
DateTime? EndDate { get; set; }
|
||||||
DateTime DateLastSaved { get; set; }
|
DateTime DateLastSaved { get; set; }
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public bool IsSeries { get; set; }
|
public bool IsSeries { get; set; }
|
||||||
public string SeriesTimerId { get; set; }
|
public string SeriesTimerId { get; set; }
|
||||||
|
public string TimerId { get; set; }
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public DateTime StartDate { get; set; }
|
public DateTime StartDate { get; set; }
|
||||||
public RecordingStatus Status { get; set; }
|
public RecordingStatus Status { get; set; }
|
||||||
|
@ -112,7 +113,7 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
|
|
||||||
public override bool CanDelete()
|
public override bool CanDelete()
|
||||||
{
|
{
|
||||||
return true;
|
return Status == RecordingStatus.Completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsAuthorizedToDelete(User user)
|
public override bool IsAuthorizedToDelete(User user)
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public bool IsSeries { get; set; }
|
public bool IsSeries { get; set; }
|
||||||
public string SeriesTimerId { get; set; }
|
public string SeriesTimerId { get; set; }
|
||||||
|
public string TimerId { get; set; }
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public DateTime StartDate { get; set; }
|
public DateTime StartDate { get; set; }
|
||||||
public RecordingStatus Status { get; set; }
|
public RecordingStatus Status { get; set; }
|
||||||
|
@ -111,7 +112,7 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
|
|
||||||
public override bool CanDelete()
|
public override bool CanDelete()
|
||||||
{
|
{
|
||||||
return true;
|
return Status == RecordingStatus.Completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsAuthorizedToDelete(User user)
|
public override bool IsAuthorizedToDelete(User user)
|
||||||
|
|
|
@ -149,7 +149,6 @@
|
||||||
<Compile Include="Entities\IHasShortOverview.cs" />
|
<Compile Include="Entities\IHasShortOverview.cs" />
|
||||||
<Compile Include="Entities\IHasSpecialFeatures.cs" />
|
<Compile Include="Entities\IHasSpecialFeatures.cs" />
|
||||||
<Compile Include="Entities\IHasStartDate.cs" />
|
<Compile Include="Entities\IHasStartDate.cs" />
|
||||||
<Compile Include="Entities\IHasThemeMedia.cs" />
|
|
||||||
<Compile Include="Entities\IHasTrailers.cs" />
|
<Compile Include="Entities\IHasTrailers.cs" />
|
||||||
<Compile Include="Entities\IHasUserData.cs" />
|
<Compile Include="Entities\IHasUserData.cs" />
|
||||||
<Compile Include="Entities\IHiddenFromDisplay.cs" />
|
<Compile Include="Entities\IHiddenFromDisplay.cs" />
|
||||||
|
|
|
@ -347,7 +347,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
var person = item as Person;
|
var person = item as Person;
|
||||||
if (person != null)
|
if (person != null)
|
||||||
{
|
{
|
||||||
person.PlaceOfBirth = val;
|
person.ProductionLocations = new List<string> { val };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -790,7 +790,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
string readerName = reader.Name;
|
string readerName = reader.Name;
|
||||||
string providerIdValue;
|
string providerIdValue;
|
||||||
if (_validProviderIds.TryGetValue(readerName, out providerIdValue))
|
if (_validProviderIds.TryGetValue(readerName, out providerIdValue))
|
||||||
|
|
|
@ -428,14 +428,6 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
||||||
|
|
||||||
return ApplyPaging(result, startIndex, limit);
|
return ApplyPaging(result, startIndex, limit);
|
||||||
}
|
}
|
||||||
if (stubType.Value == StubType.Folder)
|
|
||||||
{
|
|
||||||
var movie = item as Movie;
|
|
||||||
if (movie != null)
|
|
||||||
{
|
|
||||||
return ApplyPaging(await GetMovieItems(movie).ConfigureAwait(false), startIndex, limit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var person = item as Person;
|
var person = item as Person;
|
||||||
if (person != null)
|
if (person != null)
|
||||||
|
@ -468,14 +460,11 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
||||||
|
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
|
|
||||||
var options = _config.GetDlnaConfiguration();
|
|
||||||
|
|
||||||
var serverItems = queryResult
|
var serverItems = queryResult
|
||||||
.Items
|
.Items
|
||||||
.Select(i => new ServerItem
|
.Select(i => new ServerItem
|
||||||
{
|
{
|
||||||
Item = i,
|
Item = i
|
||||||
StubType = GetDisplayStubType(i, item, options)
|
|
||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
|
@ -519,29 +508,6 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private StubType? GetDisplayStubType(BaseItem item, BaseItem context, DlnaOptions options)
|
|
||||||
{
|
|
||||||
if (context == null || context.IsFolder)
|
|
||||||
{
|
|
||||||
var movie = item as Movie;
|
|
||||||
if (movie != null && options.EnableMovieFolders)
|
|
||||||
{
|
|
||||||
if (movie.GetTrailerIds().Count > 0 ||
|
|
||||||
movie.SpecialFeatureIds.Count > 0)
|
|
||||||
{
|
|
||||||
return StubType.Folder;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EnablePeopleDisplay(item))
|
|
||||||
{
|
|
||||||
return StubType.Folder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool EnablePeopleDisplay(BaseItem item)
|
private bool EnablePeopleDisplay(BaseItem item)
|
||||||
{
|
{
|
||||||
if (_libraryManager.GetPeopleNames(new InternalPeopleQuery
|
if (_libraryManager.GetPeopleNames(new InternalPeopleQuery
|
||||||
|
@ -556,31 +522,6 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task<QueryResult<ServerItem>> GetMovieItems(Movie item)
|
|
||||||
{
|
|
||||||
var list = new List<BaseItem>();
|
|
||||||
|
|
||||||
list.Add(item);
|
|
||||||
|
|
||||||
list.AddRange(item.GetTrailerIds().Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
|
|
||||||
list.AddRange(item.SpecialFeatureIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
|
|
||||||
|
|
||||||
var serverItems = list.Select(i => new ServerItem { Item = i, StubType = null })
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
serverItems.Add(new ServerItem
|
|
||||||
{
|
|
||||||
Item = item,
|
|
||||||
StubType = StubType.People
|
|
||||||
});
|
|
||||||
|
|
||||||
return Task.FromResult(new QueryResult<ServerItem>
|
|
||||||
{
|
|
||||||
Items = serverItems.ToArray(),
|
|
||||||
TotalRecordCount = serverItems.Count
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private ServerItem GetItemFromObjectId(string id, User user)
|
private ServerItem GetItemFromObjectId(string id, User user)
|
||||||
{
|
{
|
||||||
return DidlBuilder.IsIdRoot(id)
|
return DidlBuilder.IsIdRoot(id)
|
||||||
|
|
|
@ -220,7 +220,7 @@ namespace MediaBrowser.Dlna.Main
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cacheLength = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds * 2;
|
var cacheLength = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds;
|
||||||
_Publisher.SupportPnpRootDevice = false;
|
_Publisher.SupportPnpRootDevice = false;
|
||||||
|
|
||||||
var addresses = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).ToList();
|
var addresses = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).ToList();
|
||||||
|
|
|
@ -66,9 +66,9 @@ namespace MediaBrowser.LocalMetadata.Savers
|
||||||
|
|
||||||
XmlSaverHelpers.AddCommonNodes(person, _libraryManager, builder);
|
XmlSaverHelpers.AddCommonNodes(person, _libraryManager, builder);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(person.PlaceOfBirth))
|
if (person.ProductionLocations.Count > 0)
|
||||||
{
|
{
|
||||||
builder.Append("<PlaceOfBirth>" + SecurityElement.Escape(person.PlaceOfBirth) + "</PlaceOfBirth>");
|
builder.Append("<PlaceOfBirth>" + SecurityElement.Escape(person.ProductionLocations[0]) + "</PlaceOfBirth>");
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.Append("</Item>");
|
builder.Append("</Item>");
|
||||||
|
|
|
@ -10,7 +10,6 @@ namespace MediaBrowser.Model.Configuration
|
||||||
public int ClientDiscoveryIntervalSeconds { get; set; }
|
public int ClientDiscoveryIntervalSeconds { get; set; }
|
||||||
public int BlastAliveMessageIntervalSeconds { get; set; }
|
public int BlastAliveMessageIntervalSeconds { get; set; }
|
||||||
public string DefaultUserId { get; set; }
|
public string DefaultUserId { get; set; }
|
||||||
public bool EnableMovieFolders { get; set; }
|
|
||||||
|
|
||||||
public DlnaOptions()
|
public DlnaOptions()
|
||||||
{
|
{
|
||||||
|
|
|
@ -435,7 +435,8 @@ namespace MediaBrowser.Model.Configuration
|
||||||
Limit = 0,
|
Limit = 0,
|
||||||
Type = ImageType.Disc
|
Type = ImageType.Disc
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
DisabledMetadataFetchers = new []{ "TheAudioDB" }
|
||||||
},
|
},
|
||||||
|
|
||||||
new MetadataOptions(1, 1280)
|
new MetadataOptions(1, 1280)
|
||||||
|
@ -473,7 +474,8 @@ namespace MediaBrowser.Model.Configuration
|
||||||
Limit = 0,
|
Limit = 0,
|
||||||
Type = ImageType.Logo
|
Type = ImageType.Logo
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
DisabledMetadataFetchers = new []{ "TheAudioDB" }
|
||||||
},
|
},
|
||||||
|
|
||||||
new MetadataOptions(1, 1280)
|
new MetadataOptions(1, 1280)
|
||||||
|
|
|
@ -169,6 +169,8 @@ namespace MediaBrowser.Model.Dto
|
||||||
/// <value>The game system.</value>
|
/// <value>The game system.</value>
|
||||||
public string GameSystem { get; set; }
|
public string GameSystem { get; set; }
|
||||||
|
|
||||||
|
public string[] ProductionLocations { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the critic rating summary.
|
/// Gets or sets the critic rating summary.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1211,7 +1213,6 @@ namespace MediaBrowser.Model.Dto
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The timer identifier.</value>
|
/// <value>The timer identifier.</value>
|
||||||
public string TimerId { get; set; }
|
public string TimerId { get; set; }
|
||||||
public RecordingStatus TimerStatus { get; set; }
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the current program.
|
/// Gets or sets the current program.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -7,7 +7,6 @@ namespace MediaBrowser.Model.LiveTv
|
||||||
Scheduled,
|
Scheduled,
|
||||||
InProgress,
|
InProgress,
|
||||||
Completed,
|
Completed,
|
||||||
Aborted,
|
|
||||||
Cancelled,
|
Cancelled,
|
||||||
ConflictedOk,
|
ConflictedOk,
|
||||||
ConflictedNotOk,
|
ConflictedNotOk,
|
||||||
|
|
|
@ -68,6 +68,30 @@ namespace MediaBrowser.Model.LiveTv
|
||||||
{
|
{
|
||||||
get { return ImageTags != null && ImageTags.ContainsKey(ImageType.Primary); }
|
get { return ImageTags != null && ImageTags.ContainsKey(ImageType.Primary); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the parent thumb item id.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The parent thumb item id.</value>
|
||||||
|
public string ParentThumbItemId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the parent thumb image tag.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The parent thumb image tag.</value>
|
||||||
|
public string ParentThumbImageTag { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the parent primary image item identifier.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The parent primary image item identifier.</value>
|
||||||
|
public string ParentPrimaryImageItemId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the parent primary image tag.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The parent primary image tag.</value>
|
||||||
|
public string ParentPrimaryImageTag { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum KeepUntil
|
public enum KeepUntil
|
||||||
|
|
|
@ -32,7 +32,8 @@ namespace MediaBrowser.Model.Providers
|
||||||
public string SearchProviderName { get; set; }
|
public string SearchProviderName { get; set; }
|
||||||
|
|
||||||
public string GameSystem { get; set; }
|
public string GameSystem { get; set; }
|
||||||
|
public string Overview { get; set; }
|
||||||
|
|
||||||
public RemoteSearchResult()
|
public RemoteSearchResult()
|
||||||
{
|
{
|
||||||
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
|
@ -154,8 +154,6 @@
|
||||||
/// </summary>
|
/// </summary>
|
||||||
People,
|
People,
|
||||||
|
|
||||||
PlaceOfBirth,
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The production locations
|
/// The production locations
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -170,6 +170,14 @@ namespace MediaBrowser.Providers.Manager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!lockedFields.Contains(MetadataFields.ProductionLocations))
|
||||||
|
{
|
||||||
|
if (replaceData || target.ProductionLocations.Count == 0)
|
||||||
|
{
|
||||||
|
target.ProductionLocations = source.ProductionLocations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (replaceData || !target.VoteCount.HasValue)
|
if (replaceData || !target.VoteCount.HasValue)
|
||||||
{
|
{
|
||||||
target.VoteCount = source.VoteCount;
|
target.VoteCount = source.VoteCount;
|
||||||
|
|
|
@ -148,14 +148,10 @@ namespace MediaBrowser.Providers.Movies
|
||||||
|
|
||||||
if (movieData.production_countries != null)
|
if (movieData.production_countries != null)
|
||||||
{
|
{
|
||||||
//var hasProductionLocations = movie as IHasProductionLocations;
|
movie.ProductionLocations = movieData
|
||||||
//if (hasProductionLocations != null)
|
.production_countries
|
||||||
//{
|
.Select(i => i.name)
|
||||||
// hasProductionLocations.ProductionLocations = movieData
|
.ToList();
|
||||||
// .production_countries
|
|
||||||
// .Select(i => i.name)
|
|
||||||
// .ToList();
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
movie.SetProviderId(MetadataProviders.Tmdb, movieData.id.ToString(_usCulture));
|
movie.SetProviderId(MetadataProviders.Tmdb, movieData.id.ToString(_usCulture));
|
||||||
|
|
|
@ -85,7 +85,8 @@ namespace MediaBrowser.Providers.Music
|
||||||
{
|
{
|
||||||
var result = new RemoteSearchResult
|
var result = new RemoteSearchResult
|
||||||
{
|
{
|
||||||
Name = i.Title
|
Name = i.Title,
|
||||||
|
ProductionYear = i.Year
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(i.ReleaseId))
|
if (!string.IsNullOrWhiteSpace(i.ReleaseId))
|
||||||
|
@ -94,7 +95,7 @@ namespace MediaBrowser.Providers.Music
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrWhiteSpace(i.ReleaseGroupId))
|
if (!string.IsNullOrWhiteSpace(i.ReleaseGroupId))
|
||||||
{
|
{
|
||||||
result.SetProviderId(MetadataProviders.MusicBrainzAlbum, i.ReleaseGroupId);
|
result.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, i.ReleaseGroupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -117,16 +118,22 @@ namespace MediaBrowser.Providers.Music
|
||||||
|
|
||||||
var releaseResult = await GetReleaseResult(artistMusicBrainzId, id.GetAlbumArtist(), id.Name, cancellationToken).ConfigureAwait(false);
|
var releaseResult = await GetReleaseResult(artistMusicBrainzId, id.GetAlbumArtist(), id.Name, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(releaseResult.ReleaseId))
|
if (releaseResult != null)
|
||||||
{
|
{
|
||||||
releaseId = releaseResult.ReleaseId;
|
if (!string.IsNullOrEmpty(releaseResult.ReleaseId))
|
||||||
result.HasMetadata = true;
|
{
|
||||||
}
|
releaseId = releaseResult.ReleaseId;
|
||||||
|
result.HasMetadata = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(releaseResult.ReleaseGroupId))
|
if (!string.IsNullOrEmpty(releaseResult.ReleaseGroupId))
|
||||||
{
|
{
|
||||||
releaseGroupId = releaseResult.ReleaseGroupId;
|
releaseGroupId = releaseResult.ReleaseGroupId;
|
||||||
result.HasMetadata = true;
|
result.HasMetadata = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Item.ProductionYear = releaseResult.Year;
|
||||||
|
result.Item.Overview = releaseResult.Overview;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,6 +212,8 @@ namespace MediaBrowser.Providers.Music
|
||||||
public string ReleaseId;
|
public string ReleaseId;
|
||||||
public string ReleaseGroupId;
|
public string ReleaseGroupId;
|
||||||
public string Title;
|
public string Title;
|
||||||
|
public string Overview;
|
||||||
|
public int? Year;
|
||||||
|
|
||||||
public static List<ReleaseResult> Parse(XmlDocument doc, int? limit = null)
|
public static List<ReleaseResult> Parse(XmlDocument doc, int? limit = null)
|
||||||
{
|
{
|
||||||
|
@ -237,7 +246,9 @@ namespace MediaBrowser.Providers.Music
|
||||||
{
|
{
|
||||||
ReleaseId = releaseId,
|
ReleaseId = releaseId,
|
||||||
ReleaseGroupId = releaseGroupId,
|
ReleaseGroupId = releaseGroupId,
|
||||||
Title = GetTitleFromReleaseNode(node)
|
Title = GetValueFromReleaseNode(node, "title"),
|
||||||
|
Overview = GetValueFromReleaseNode(node, "annotation"),
|
||||||
|
Year = GetYearFromReleaseNode(node, "date")
|
||||||
});
|
});
|
||||||
|
|
||||||
if (limit.HasValue && list.Count >= limit.Value)
|
if (limit.HasValue && list.Count >= limit.Value)
|
||||||
|
@ -251,14 +262,37 @@ namespace MediaBrowser.Providers.Music
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetTitleFromReleaseNode(XmlNode node)
|
private static int? GetYearFromReleaseNode(XmlNode node, string name)
|
||||||
{
|
{
|
||||||
var subNodes = node.ChildNodes;
|
var subNodes = node.ChildNodes;
|
||||||
if (subNodes != null)
|
if (subNodes != null)
|
||||||
{
|
{
|
||||||
foreach (var subNode in subNodes.Cast<XmlNode>())
|
foreach (var subNode in subNodes.Cast<XmlNode>())
|
||||||
{
|
{
|
||||||
if (string.Equals(subNode.Name, "title", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(subNode.Name, name, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
DateTime date;
|
||||||
|
if (DateTime.TryParse(subNode.InnerText, out date))
|
||||||
|
{
|
||||||
|
return date.Year;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetValueFromReleaseNode(XmlNode node, string name)
|
||||||
|
{
|
||||||
|
var subNodes = node.ChildNodes;
|
||||||
|
if (subNodes != null)
|
||||||
|
{
|
||||||
|
foreach (var subNode in subNodes.Cast<XmlNode>())
|
||||||
|
{
|
||||||
|
if (string.Equals(subNode.Name, name, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return subNode.InnerText;
|
return subNode.InnerText;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace MediaBrowser.Providers.Music
|
||||||
if (node.Attributes != null)
|
if (node.Attributes != null)
|
||||||
{
|
{
|
||||||
string name = null;
|
string name = null;
|
||||||
|
string overview = null;
|
||||||
string mbzId = node.Attributes["id"].Value;
|
string mbzId = node.Attributes["id"].Value;
|
||||||
|
|
||||||
foreach (var child in node.ChildNodes.Cast<XmlNode>())
|
foreach (var child in node.ChildNodes.Cast<XmlNode>())
|
||||||
|
@ -94,7 +94,10 @@ namespace MediaBrowser.Providers.Music
|
||||||
if (string.Equals(child.Name, "name", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(child.Name, "name", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
name = child.InnerText;
|
name = child.InnerText;
|
||||||
break;
|
}
|
||||||
|
if (string.Equals(child.Name, "annotation", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
overview = child.InnerText;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +105,8 @@ namespace MediaBrowser.Providers.Music
|
||||||
{
|
{
|
||||||
var result = new RemoteSearchResult
|
var result = new RemoteSearchResult
|
||||||
{
|
{
|
||||||
Name = name
|
Name = name,
|
||||||
|
Overview = overview
|
||||||
};
|
};
|
||||||
|
|
||||||
result.SetProviderId(MetadataProviders.MusicBrainzArtist, mbzId);
|
result.SetProviderId(MetadataProviders.MusicBrainzArtist, mbzId);
|
||||||
|
@ -135,6 +139,7 @@ namespace MediaBrowser.Providers.Music
|
||||||
{
|
{
|
||||||
musicBrainzId = singleResult.GetProviderId(MetadataProviders.MusicBrainzArtist);
|
musicBrainzId = singleResult.GetProviderId(MetadataProviders.MusicBrainzArtist);
|
||||||
//result.Item.Name = singleResult.Name;
|
//result.Item.Name = singleResult.Name;
|
||||||
|
result.Item.Overview = singleResult.Overview;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,11 @@ namespace MediaBrowser.Providers.People
|
||||||
|
|
||||||
item.Name = info.name;
|
item.Name = info.name;
|
||||||
item.HomePageUrl = info.homepage;
|
item.HomePageUrl = info.homepage;
|
||||||
item.PlaceOfBirth = info.place_of_birth;
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(info.place_of_birth))
|
||||||
|
{
|
||||||
|
item.ProductionLocations = new List<string> { info.place_of_birth };
|
||||||
|
}
|
||||||
item.Overview = info.biography;
|
item.Overview = info.biography;
|
||||||
|
|
||||||
DateTime date;
|
DateTime date;
|
||||||
|
|
|
@ -15,14 +15,6 @@ namespace MediaBrowser.Providers.People
|
||||||
protected override void MergeData(MetadataResult<Person> source, MetadataResult<Person> target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
|
protected override void MergeData(MetadataResult<Person> source, MetadataResult<Person> target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
|
||||||
{
|
{
|
||||||
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
|
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
|
||||||
|
|
||||||
var sourceItem = source.Item;
|
|
||||||
var targetItem = target.Item;
|
|
||||||
|
|
||||||
if (replaceData || string.IsNullOrEmpty(targetItem.PlaceOfBirth))
|
|
||||||
{
|
|
||||||
targetItem.PlaceOfBirth = sourceItem.PlaceOfBirth;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PersonMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
|
public PersonMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
|
||||||
|
|
|
@ -1577,97 +1577,5 @@ namespace MediaBrowser.Server.Implementations.Channels
|
||||||
|
|
||||||
return await _libraryManager.GetNamedView(name, "channels", "zz_" + name, cancellationToken).ConfigureAwait(false);
|
return await _libraryManager.GetNamedView(name, "channels", "zz_" + name, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DownloadChannelItem(BaseItem item, string destination,
|
|
||||||
IProgress<double> progress, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var sources = await GetDynamicMediaSources(item, cancellationToken)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
var list = sources.Where(i => i.Protocol == MediaProtocol.Http).ToList();
|
|
||||||
|
|
||||||
foreach (var source in list)
|
|
||||||
{
|
|
||||||
await TryDownloadChannelItem(source, item, destination, progress, cancellationToken).ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task TryDownloadChannelItem(MediaSourceInfo source,
|
|
||||||
BaseItem item,
|
|
||||||
string destination,
|
|
||||||
IProgress<double> progress,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var options = new HttpRequestOptions
|
|
||||||
{
|
|
||||||
CancellationToken = cancellationToken,
|
|
||||||
Url = source.Path,
|
|
||||||
Progress = new Progress<double>()
|
|
||||||
};
|
|
||||||
|
|
||||||
var channel = GetChannel(item.ChannelId);
|
|
||||||
var channelProvider = GetChannelProvider(channel);
|
|
||||||
var features = channelProvider.GetChannelFeatures();
|
|
||||||
|
|
||||||
if (!features.SupportsContentDownloading)
|
|
||||||
{
|
|
||||||
throw new ArgumentException("The channel does not support downloading.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var limit = features.DailyDownloadLimit;
|
|
||||||
|
|
||||||
foreach (var header in source.RequiredHttpHeaders)
|
|
||||||
{
|
|
||||||
options.RequestHeaders[header.Key] = header.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
_fileSystem.CreateDirectory(Path.GetDirectoryName(destination));
|
|
||||||
|
|
||||||
// Determine output extension
|
|
||||||
var response = await _httpClient.GetTempFileResponse(options).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (response.ContentType.StartsWith("text/html"))
|
|
||||||
{
|
|
||||||
throw new HttpException("File not found")
|
|
||||||
{
|
|
||||||
StatusCode = HttpStatusCode.NotFound
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase) && response.ContentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
var extension = response.ContentType.Split('/')
|
|
||||||
.Last()
|
|
||||||
.Replace("quicktime", "mov", StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
destination += "." + extension;
|
|
||||||
}
|
|
||||||
else if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) && response.ContentType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
var extension = response.ContentType.Replace("audio/mpeg", "audio/mp3", StringComparison.OrdinalIgnoreCase)
|
|
||||||
.Split('/')
|
|
||||||
.Last();
|
|
||||||
|
|
||||||
destination += "." + extension;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_fileSystem.DeleteFile(response.TempFilePath);
|
|
||||||
|
|
||||||
throw new ApplicationException("Unexpected response type encountered: " + response.ContentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
_fileSystem.CopyFile(response.TempFilePath, destination, true);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_fileSystem.DeleteFile(response.TempFilePath);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -907,15 +907,6 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||||
dto.Keywords = item.Keywords;
|
dto.Keywords = item.Keywords;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fields.Contains(ItemFields.PlaceOfBirth))
|
|
||||||
{
|
|
||||||
var person = item as Person;
|
|
||||||
if (person != null)
|
|
||||||
{
|
|
||||||
dto.PlaceOfBirth = person.PlaceOfBirth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var hasAspectRatio = item as IHasAspectRatio;
|
var hasAspectRatio = item as IHasAspectRatio;
|
||||||
if (hasAspectRatio != null)
|
if (hasAspectRatio != null)
|
||||||
{
|
{
|
||||||
|
@ -1432,6 +1423,11 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||||
SetBookProperties(dto, book);
|
SetBookProperties(dto, book);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.ProductionLocations.Count > 0 || item is Movie)
|
||||||
|
{
|
||||||
|
dto.ProductionLocations = item.ProductionLocations.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
var photo = item as Photo;
|
var photo = item as Photo;
|
||||||
if (photo != null)
|
if (photo != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||||
public Container Container { get; set; }
|
public Container Container { get; set; }
|
||||||
private readonly HttpListenerRequest request;
|
private readonly HttpListenerRequest request;
|
||||||
private readonly IHttpResponse response;
|
private readonly IHttpResponse response;
|
||||||
private IMemoryStreamProvider _memoryStreamProvider;
|
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
||||||
|
|
||||||
public WebSocketSharpRequest(HttpListenerContext httpContext, string operationName, RequestAttributes requestAttributes, ILogger logger, IMemoryStreamProvider memoryStreamProvider)
|
public WebSocketSharpRequest(HttpListenerContext httpContext, string operationName, RequestAttributes requestAttributes, ILogger logger, IMemoryStreamProvider memoryStreamProvider)
|
||||||
{
|
{
|
||||||
|
|
|
@ -335,15 +335,6 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the item in library cache.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item">The item.</param>
|
|
||||||
private void UpdateItemInLibraryCache(BaseItem item)
|
|
||||||
{
|
|
||||||
RegisterItem(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterItem(BaseItem item)
|
public void RegisterItem(BaseItem item)
|
||||||
{
|
{
|
||||||
if (item == null)
|
if (item == null)
|
||||||
|
@ -1777,7 +1768,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
|
|
||||||
foreach (var item in list)
|
foreach (var item in list)
|
||||||
{
|
{
|
||||||
UpdateItemInLibraryCache(item);
|
RegisterItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ItemAdded != null)
|
if (ItemAdded != null)
|
||||||
|
@ -1818,7 +1809,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
|
|
||||||
await ItemRepository.SaveItem(item, cancellationToken).ConfigureAwait(false);
|
await ItemRepository.SaveItem(item, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
UpdateItemInLibraryCache(item);
|
RegisterItem(item);
|
||||||
|
|
||||||
if (ItemUpdated != null)
|
if (ItemUpdated != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,8 +54,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
|
||||||
if (!args.IsDirectory) return null;
|
if (!args.IsDirectory) return null;
|
||||||
|
|
||||||
// Avoid mis-identifying top folders
|
// Avoid mis-identifying top folders
|
||||||
if (args.Parent.IsRoot) return null;
|
|
||||||
if (args.HasParent<MusicAlbum>()) return null;
|
if (args.HasParent<MusicAlbum>()) return null;
|
||||||
|
if (args.Parent.IsRoot) return null;
|
||||||
|
|
||||||
var collectionType = args.GetCollectionType();
|
var collectionType = args.GetCollectionType();
|
||||||
|
|
||||||
|
|
|
@ -51,9 +51,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
|
||||||
{
|
{
|
||||||
if (!args.IsDirectory) return null;
|
if (!args.IsDirectory) return null;
|
||||||
|
|
||||||
// Avoid mis-identifying top folders
|
|
||||||
if (args.Parent.IsRoot) return null;
|
|
||||||
|
|
||||||
// Don't allow nested artists
|
// Don't allow nested artists
|
||||||
if (args.HasParent<MusicArtist>() || args.HasParent<MusicAlbum>())
|
if (args.HasParent<MusicArtist>() || args.HasParent<MusicAlbum>())
|
||||||
{
|
{
|
||||||
|
@ -70,12 +67,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.IsDirectory)
|
if (args.ContainsFileSystemEntryByName("artist.nfo"))
|
||||||
{
|
{
|
||||||
if (args.ContainsFileSystemEntryByName("artist.nfo"))
|
return new MusicArtist();
|
||||||
{
|
|
||||||
return new MusicArtist();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_config.Configuration.EnableSimpleArtistDetection)
|
if (_config.Configuration.EnableSimpleArtistDetection)
|
||||||
|
@ -83,6 +77,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avoid mis-identifying top folders
|
||||||
|
if (args.Parent.IsRoot) return null;
|
||||||
|
|
||||||
var directoryService = args.DirectoryService;
|
var directoryService = args.DirectoryService;
|
||||||
|
|
||||||
var albumResolver = new MusicAlbumResolver(_logger, _fileSystem, _libraryManager);
|
var albumResolver = new MusicAlbumResolver(_logger, _fileSystem, _libraryManager);
|
||||||
|
|
|
@ -51,7 +51,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
|
||||||
base.SetInitialItemValues(item, args);
|
base.SetInitialItemValues(item, args);
|
||||||
|
|
||||||
item.IsRoot = args.Parent == null;
|
item.IsRoot = args.Parent == null;
|
||||||
item.IsPhysicalRoot = args.IsPhysicalRoot;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,15 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args.ContainsFileSystemEntryByName("tvshow.nfo"))
|
||||||
|
{
|
||||||
|
return new Series
|
||||||
|
{
|
||||||
|
Path = args.Path,
|
||||||
|
Name = Path.GetFileName(args.Path)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var collectionType = args.GetCollectionType();
|
var collectionType = args.GetCollectionType();
|
||||||
if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
@ -72,23 +81,20 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (string.IsNullOrWhiteSpace(collectionType))
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(collectionType))
|
if (args.Parent.IsRoot)
|
||||||
{
|
{
|
||||||
if (args.Parent.IsRoot)
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager, args.GetLibraryOptions(), false))
|
||||||
|
{
|
||||||
|
return new Series
|
||||||
{
|
{
|
||||||
return null;
|
Path = args.Path,
|
||||||
}
|
Name = Path.GetFileName(args.Path)
|
||||||
if (IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager, args.GetLibraryOptions(), false) ||
|
};
|
||||||
args.ContainsFileSystemEntryByName("tvshow.nfo"))
|
|
||||||
{
|
|
||||||
return new Series
|
|
||||||
{
|
|
||||||
Path = args.Path,
|
|
||||||
Name = Path.GetFileName(args.Path)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ using System.Threading.Tasks;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using CommonIO;
|
using CommonIO;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
|
@ -38,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
{
|
{
|
||||||
public class EmbyTV : ILiveTvService, ISupportsDirectStreamProvider, ISupportsNewTimerIds, IDisposable
|
public class EmbyTV : ILiveTvService, ISupportsDirectStreamProvider, ISupportsNewTimerIds, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IApplicationHost _appHpst;
|
private readonly IServerApplicationHost _appHost;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly IServerConfigurationManager _config;
|
private readonly IServerConfigurationManager _config;
|
||||||
|
@ -64,11 +65,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
private readonly ConcurrentDictionary<string, ActiveRecordingInfo> _activeRecordings =
|
private readonly ConcurrentDictionary<string, ActiveRecordingInfo> _activeRecordings =
|
||||||
new ConcurrentDictionary<string, ActiveRecordingInfo>(StringComparer.OrdinalIgnoreCase);
|
new ConcurrentDictionary<string, ActiveRecordingInfo>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService, IMediaEncoder mediaEncoder)
|
public EmbyTV(IServerApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService, IMediaEncoder mediaEncoder)
|
||||||
{
|
{
|
||||||
Current = this;
|
Current = this;
|
||||||
|
|
||||||
_appHpst = appHost;
|
_appHost = appHost;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
@ -293,7 +294,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
|
|
||||||
status.Tuners = list;
|
status.Tuners = list;
|
||||||
status.Status = LiveTvServiceStatus.Ok;
|
status.Status = LiveTvServiceStatus.Ok;
|
||||||
status.Version = _appHpst.ApplicationVersion.ToString();
|
status.Version = _appHost.ApplicationVersion.ToString();
|
||||||
status.IsVisible = false;
|
status.IsVisible = false;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -659,7 +660,63 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
|
|
||||||
public async Task<IEnumerable<RecordingInfo>> GetRecordingsAsync(CancellationToken cancellationToken)
|
public async Task<IEnumerable<RecordingInfo>> GetRecordingsAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return new List<RecordingInfo>();
|
return _activeRecordings.Values.ToList().Select(GetRecordingInfo).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetActiveRecordingPath(string id)
|
||||||
|
{
|
||||||
|
ActiveRecordingInfo info;
|
||||||
|
|
||||||
|
if (_activeRecordings.TryGetValue(id, out info))
|
||||||
|
{
|
||||||
|
return info.Path;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RecordingInfo GetRecordingInfo(ActiveRecordingInfo info)
|
||||||
|
{
|
||||||
|
var timer = info.Timer;
|
||||||
|
var program = info.Program;
|
||||||
|
|
||||||
|
var result = new RecordingInfo
|
||||||
|
{
|
||||||
|
ChannelId = timer.ChannelId,
|
||||||
|
CommunityRating = timer.CommunityRating,
|
||||||
|
DateLastUpdated = DateTime.UtcNow,
|
||||||
|
EndDate = timer.EndDate,
|
||||||
|
EpisodeTitle = timer.EpisodeTitle,
|
||||||
|
Genres = timer.Genres,
|
||||||
|
Id = "recording" + timer.Id,
|
||||||
|
IsKids = timer.IsKids,
|
||||||
|
IsMovie = timer.IsMovie,
|
||||||
|
IsNews = timer.IsNews,
|
||||||
|
IsRepeat = timer.IsRepeat,
|
||||||
|
IsSeries = timer.IsProgramSeries,
|
||||||
|
IsSports = timer.IsSports,
|
||||||
|
Name = timer.Name,
|
||||||
|
OfficialRating = timer.OfficialRating,
|
||||||
|
OriginalAirDate = timer.OriginalAirDate,
|
||||||
|
Overview = timer.Overview,
|
||||||
|
ProgramId = timer.ProgramId,
|
||||||
|
SeriesTimerId = timer.SeriesTimerId,
|
||||||
|
StartDate = timer.StartDate,
|
||||||
|
Status = RecordingStatus.InProgress,
|
||||||
|
TimerId = timer.Id
|
||||||
|
};
|
||||||
|
|
||||||
|
if (program != null)
|
||||||
|
{
|
||||||
|
result.Audio = program.Audio;
|
||||||
|
result.ImagePath = program.ImagePath;
|
||||||
|
result.ImageUrl = program.ImageUrl;
|
||||||
|
result.IsHD = program.IsHD;
|
||||||
|
result.IsLive = program.IsLive;
|
||||||
|
result.IsPremiere = program.IsPremiere;
|
||||||
|
result.ShowId = program.ShowId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<IEnumerable<TimerInfo>> GetTimersAsync(CancellationToken cancellationToken)
|
public Task<IEnumerable<TimerInfo>> GetTimersAsync(CancellationToken cancellationToken)
|
||||||
|
@ -954,7 +1011,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
|
|
||||||
public Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken)
|
public Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
ActiveRecordingInfo info;
|
||||||
|
|
||||||
|
recordingId = recordingId.Replace("recording", string.Empty);
|
||||||
|
|
||||||
|
if (_activeRecordings.TryGetValue(recordingId, out info))
|
||||||
|
{
|
||||||
|
return Task.FromResult(new List<MediaSourceInfo>
|
||||||
|
{
|
||||||
|
new MediaSourceInfo
|
||||||
|
{
|
||||||
|
Path = _appHost.GetLocalApiUrl("localhost") + "/LiveTv/LiveRecordings/" + recordingId + "/stream",
|
||||||
|
Id = recordingId,
|
||||||
|
SupportsDirectPlay = false,
|
||||||
|
SupportsDirectStream = true,
|
||||||
|
SupportsTranscoding = true,
|
||||||
|
IsInfiniteStream = true,
|
||||||
|
RequiresOpening = false,
|
||||||
|
RequiresClosing = false,
|
||||||
|
Protocol = Model.MediaInfo.MediaProtocol.Http,
|
||||||
|
BufferMs = 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new FileNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CloseLiveStream(string id, CancellationToken cancellationToken)
|
public async Task CloseLiveStream(string id, CancellationToken cancellationToken)
|
||||||
|
@ -1031,7 +1112,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
var activeRecordingInfo = new ActiveRecordingInfo
|
var activeRecordingInfo = new ActiveRecordingInfo
|
||||||
{
|
{
|
||||||
CancellationTokenSource = new CancellationTokenSource(),
|
CancellationTokenSource = new CancellationTokenSource(),
|
||||||
TimerId = timer.Id
|
Timer = timer
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_activeRecordings.TryAdd(timer.Id, activeRecordingInfo))
|
if (_activeRecordings.TryAdd(timer.Id, activeRecordingInfo))
|
||||||
|
@ -1168,6 +1249,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
if (programInfo != null)
|
if (programInfo != null)
|
||||||
{
|
{
|
||||||
RecordingHelper.CopyProgramInfoToTimerInfo(programInfo, timer);
|
RecordingHelper.CopyProgramInfoToTimerInfo(programInfo, timer);
|
||||||
|
activeRecordingInfo.Program = programInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
string seriesPath = null;
|
string seriesPath = null;
|
||||||
|
@ -1394,7 +1476,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasRecordingAtPath = _activeRecordings.Values.ToList().Any(i => string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase) && !string.Equals(i.TimerId, timerId, StringComparison.OrdinalIgnoreCase));
|
var hasRecordingAtPath = _activeRecordings
|
||||||
|
.Values
|
||||||
|
.ToList()
|
||||||
|
.Any(i => string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase) && !string.Equals(i.Timer.Id, timerId, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
if (hasRecordingAtPath)
|
if (hasRecordingAtPath)
|
||||||
{
|
{
|
||||||
|
@ -1878,7 +1963,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||||
class ActiveRecordingInfo
|
class ActiveRecordingInfo
|
||||||
{
|
{
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public string TimerId { get; set; }
|
public TimerInfo Timer { get; set; }
|
||||||
|
public ProgramInfo Program { get; set; }
|
||||||
public CancellationTokenSource CancellationTokenSource { get; set; }
|
public CancellationTokenSource CancellationTokenSource { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ using MediaBrowser.Model.LiveTv;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
@ -125,6 +126,34 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
|
|
||||||
dto.DayPattern = info.Days == null ? null : GetDayPattern(info.Days);
|
dto.DayPattern = info.Days == null ? null : GetDayPattern(info.Days);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(info.SeriesId))
|
||||||
|
{
|
||||||
|
var program = _libraryManager.GetItemList(new InternalItemsQuery
|
||||||
|
{
|
||||||
|
IncludeItemTypes = new string[] { typeof(LiveTvProgram).Name },
|
||||||
|
ExternalSeriesId = info.SeriesId,
|
||||||
|
Limit = 1,
|
||||||
|
ImageTypes = new ImageType[] { ImageType.Primary }
|
||||||
|
|
||||||
|
}).FirstOrDefault();
|
||||||
|
|
||||||
|
if (program != null)
|
||||||
|
{
|
||||||
|
var image = program.GetImageInfo(ImageType.Primary, 0);
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dto.ParentPrimaryImageTag = _imageProcessor.GetImageCacheTag(program, image);
|
||||||
|
dto.ParentPrimaryImageItemId = program.Id.ToString("N");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -235,20 +235,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
return await GetLiveStream(id, mediaSourceId, true, cancellationToken).ConfigureAwait(false);
|
return await GetLiveStream(id, mediaSourceId, true, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(string id, CancellationToken cancellationToken)
|
public async Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(IHasMediaSources item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var item = await GetInternalRecording(id, cancellationToken).ConfigureAwait(false);
|
var baseItem = (BaseItem)item;
|
||||||
var service = GetService(item);
|
var service = GetService(baseItem);
|
||||||
|
|
||||||
return await service.GetRecordingStreamMediaSources(id, cancellationToken).ConfigureAwait(false);
|
return await service.GetRecordingStreamMediaSources(baseItem.ExternalId, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(string id, CancellationToken cancellationToken)
|
public async Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(IHasMediaSources item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var item = GetInternalChannel(id);
|
var baseItem = (LiveTvChannel)item;
|
||||||
var service = GetService(item);
|
var service = GetService(baseItem);
|
||||||
|
|
||||||
var sources = await service.GetChannelStreamMediaSources(item.ExternalId, cancellationToken).ConfigureAwait(false);
|
var sources = await service.GetChannelStreamMediaSources(baseItem.ExternalId, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
if (sources.Count == 0)
|
if (sources.Count == 0)
|
||||||
{
|
{
|
||||||
|
@ -259,7 +259,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
|
|
||||||
foreach (var source in list)
|
foreach (var source in list)
|
||||||
{
|
{
|
||||||
Normalize(source, service, item.ChannelType == ChannelType.TV);
|
Normalize(source, service, baseItem.ChannelType == ChannelType.TV);
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
|
@ -738,6 +738,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
recording.IsRepeat = info.IsRepeat;
|
recording.IsRepeat = info.IsRepeat;
|
||||||
recording.IsSports = info.IsSports;
|
recording.IsSports = info.IsSports;
|
||||||
recording.SeriesTimerId = info.SeriesTimerId;
|
recording.SeriesTimerId = info.SeriesTimerId;
|
||||||
|
recording.TimerId = info.TimerId;
|
||||||
recording.StartDate = info.StartDate;
|
recording.StartDate = info.StartDate;
|
||||||
|
|
||||||
if (!dataChanged)
|
if (!dataChanged)
|
||||||
|
@ -1083,10 +1084,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
|
|
||||||
if (timer != null)
|
if (timer != null)
|
||||||
{
|
{
|
||||||
program.TimerId = _tvDtoService.GetInternalTimerId(serviceName, timer.Id)
|
if (timer.Status != RecordingStatus.Cancelled && timer.Status != RecordingStatus.Error)
|
||||||
.ToString("N");
|
{
|
||||||
|
program.TimerId = _tvDtoService.GetInternalTimerId(serviceName, timer.Id)
|
||||||
|
.ToString("N");
|
||||||
|
|
||||||
program.TimerStatus = timer.Status;
|
program.Status = timer.Status.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(timer.SeriesTimerId))
|
if (!string.IsNullOrEmpty(timer.SeriesTimerId))
|
||||||
{
|
{
|
||||||
|
@ -1432,7 +1436,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
private DateTime _lastRecordingRefreshTime;
|
private DateTime _lastRecordingRefreshTime;
|
||||||
private async Task RefreshRecordings(CancellationToken cancellationToken)
|
private async Task RefreshRecordings(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
const int cacheMinutes = 5;
|
const int cacheMinutes = 3;
|
||||||
|
|
||||||
if ((DateTime.UtcNow - _lastRecordingRefreshTime).TotalMinutes < cacheMinutes)
|
if ((DateTime.UtcNow - _lastRecordingRefreshTime).TotalMinutes < cacheMinutes)
|
||||||
{
|
{
|
||||||
|
@ -1482,7 +1486,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
|
|
||||||
private QueryResult<BaseItem> GetEmbyRecordings(RecordingQuery query, DtoOptions dtoOptions, User user)
|
private QueryResult<BaseItem> GetEmbyRecordings(RecordingQuery query, DtoOptions dtoOptions, User user)
|
||||||
{
|
{
|
||||||
if (user == null || (query.IsInProgress ?? false))
|
if (user == null)
|
||||||
|
{
|
||||||
|
return new QueryResult<BaseItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((query.IsInProgress ?? false))
|
||||||
{
|
{
|
||||||
return new QueryResult<BaseItem>();
|
return new QueryResult<BaseItem>();
|
||||||
}
|
}
|
||||||
|
@ -1628,7 +1637,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
return new QueryResult<BaseItem>();
|
return new QueryResult<BaseItem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_services.Count == 1)
|
if (_services.Count == 1 && !(query.IsInProgress ?? false))
|
||||||
{
|
{
|
||||||
return GetEmbyRecordings(query, new DtoOptions(), user);
|
return GetEmbyRecordings(query, new DtoOptions(), user);
|
||||||
}
|
}
|
||||||
|
@ -1824,6 +1833,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
? null
|
? null
|
||||||
: _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N");
|
: _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N");
|
||||||
|
|
||||||
|
dto.TimerId = string.IsNullOrEmpty(info.TimerId)
|
||||||
|
? null
|
||||||
|
: _tvDtoService.GetInternalTimerId(service.Name, info.TimerId).ToString("N");
|
||||||
|
|
||||||
dto.StartDate = info.StartDate;
|
dto.StartDate = info.StartDate;
|
||||||
dto.RecordingStatus = info.Status;
|
dto.RecordingStatus = info.Status;
|
||||||
dto.IsRepeat = info.IsRepeat;
|
dto.IsRepeat = info.IsRepeat;
|
||||||
|
|
|
@ -65,12 +65,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
{
|
{
|
||||||
if (item is ILiveTvRecording)
|
if (item is ILiveTvRecording)
|
||||||
{
|
{
|
||||||
sources = await _liveTvManager.GetRecordingMediaSources(item.Id.ToString("N"), cancellationToken)
|
sources = await _liveTvManager.GetRecordingMediaSources(item, cancellationToken)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sources = await _liveTvManager.GetChannelMediaSources(item.Id.ToString("N"), cancellationToken)
|
sources = await _liveTvManager.GetChannelMediaSources(item, cancellationToken)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,13 @@ using System.Threading.Tasks;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.IO;
|
using MediaBrowser.Common.IO;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
|
using MediaBrowser.Controller.Collections;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Playlists;
|
using MediaBrowser.Controller.Playlists;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.LiveTv;
|
using MediaBrowser.Model.LiveTv;
|
||||||
|
using MediaBrowser.Server.Implementations.Devices;
|
||||||
|
using MediaBrowser.Server.Implementations.Playlists;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.Persistence
|
namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
{
|
{
|
||||||
|
@ -279,6 +282,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
_connection.AddColumn(Logger, "TypedBaseItems", "Keywords", "Text");
|
_connection.AddColumn(Logger, "TypedBaseItems", "Keywords", "Text");
|
||||||
_connection.AddColumn(Logger, "TypedBaseItems", "ProviderIds", "Text");
|
_connection.AddColumn(Logger, "TypedBaseItems", "ProviderIds", "Text");
|
||||||
_connection.AddColumn(Logger, "TypedBaseItems", "Images", "Text");
|
_connection.AddColumn(Logger, "TypedBaseItems", "Images", "Text");
|
||||||
|
_connection.AddColumn(Logger, "TypedBaseItems", "ProductionLocations", "Text");
|
||||||
|
_connection.AddColumn(Logger, "TypedBaseItems", "ThemeSongIds", "Text");
|
||||||
|
_connection.AddColumn(Logger, "TypedBaseItems", "ThemeVideoIds", "Text");
|
||||||
|
|
||||||
_connection.AddColumn(Logger, "UserDataKeys", "Priority", "INT");
|
_connection.AddColumn(Logger, "UserDataKeys", "Priority", "INT");
|
||||||
_connection.AddColumn(Logger, "ItemValues", "CleanValue", "Text");
|
_connection.AddColumn(Logger, "ItemValues", "CleanValue", "Text");
|
||||||
|
@ -428,7 +434,10 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
"Tagline",
|
"Tagline",
|
||||||
"Keywords",
|
"Keywords",
|
||||||
"ProviderIds",
|
"ProviderIds",
|
||||||
"Images"
|
"Images",
|
||||||
|
"ProductionLocations",
|
||||||
|
"ThemeSongIds",
|
||||||
|
"ThemeVideoIds"
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly string[] _mediaStreamSaveColumns =
|
private readonly string[] _mediaStreamSaveColumns =
|
||||||
|
@ -556,7 +565,10 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
"Tagline",
|
"Tagline",
|
||||||
"Keywords",
|
"Keywords",
|
||||||
"ProviderIds",
|
"ProviderIds",
|
||||||
"Images"
|
"Images",
|
||||||
|
"ProductionLocations",
|
||||||
|
"ThemeSongIds",
|
||||||
|
"ThemeVideoIds"
|
||||||
};
|
};
|
||||||
_saveItemCommand = _connection.CreateCommand();
|
_saveItemCommand = _connection.CreateCommand();
|
||||||
_saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
|
_saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
|
||||||
|
@ -742,7 +754,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
|
|
||||||
_saveItemCommand.GetParameter(index++).Value = item.Id;
|
_saveItemCommand.GetParameter(index++).Value = item.Id;
|
||||||
_saveItemCommand.GetParameter(index++).Value = item.GetType().FullName;
|
_saveItemCommand.GetParameter(index++).Value = item.GetType().FullName;
|
||||||
_saveItemCommand.GetParameter(index++).Value = _jsonSerializer.SerializeToBytes(item, _memoryStreamProvider);
|
|
||||||
|
if (TypeRequiresDeserialization(item.GetType()))
|
||||||
|
{
|
||||||
|
_saveItemCommand.GetParameter(index++).Value = _jsonSerializer.SerializeToBytes(item, _memoryStreamProvider);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_saveItemCommand.GetParameter(index++).Value = null;
|
||||||
|
}
|
||||||
|
|
||||||
_saveItemCommand.GetParameter(index++).Value = item.Path;
|
_saveItemCommand.GetParameter(index++).Value = item.Path;
|
||||||
|
|
||||||
|
@ -999,10 +1019,46 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
_saveItemCommand.GetParameter(index++).Value = item.ExternalSeriesId;
|
_saveItemCommand.GetParameter(index++).Value = item.ExternalSeriesId;
|
||||||
_saveItemCommand.GetParameter(index++).Value = item.ShortOverview;
|
_saveItemCommand.GetParameter(index++).Value = item.ShortOverview;
|
||||||
_saveItemCommand.GetParameter(index++).Value = item.Tagline;
|
_saveItemCommand.GetParameter(index++).Value = item.Tagline;
|
||||||
_saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Keywords.ToArray());
|
|
||||||
|
if (item.Keywords.Count > 0)
|
||||||
|
{
|
||||||
|
_saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Keywords.ToArray());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_saveItemCommand.GetParameter(index++).Value = null;
|
||||||
|
}
|
||||||
|
|
||||||
_saveItemCommand.GetParameter(index++).Value = SerializeProviderIds(item);
|
_saveItemCommand.GetParameter(index++).Value = SerializeProviderIds(item);
|
||||||
_saveItemCommand.GetParameter(index++).Value = SerializeImages(item);
|
_saveItemCommand.GetParameter(index++).Value = SerializeImages(item);
|
||||||
|
|
||||||
|
if (item.ProductionLocations.Count > 0)
|
||||||
|
{
|
||||||
|
_saveItemCommand.GetParameter(index++).Value = string.Join("|", item.ProductionLocations.ToArray());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_saveItemCommand.GetParameter(index++).Value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.ThemeSongIds.Count > 0)
|
||||||
|
{
|
||||||
|
_saveItemCommand.GetParameter(index++).Value = string.Join("|", item.ThemeSongIds.Select(i => i.ToString("N")).ToArray());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_saveItemCommand.GetParameter(index++).Value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.ThemeVideoIds.Count > 0)
|
||||||
|
{
|
||||||
|
_saveItemCommand.GetParameter(index++).Value = string.Join("|", item.ThemeVideoIds.Select(i => i.ToString("N")).ToArray());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_saveItemCommand.GetParameter(index++).Value = null;
|
||||||
|
}
|
||||||
|
|
||||||
_saveItemCommand.Transaction = transaction;
|
_saveItemCommand.Transaction = transaction;
|
||||||
|
|
||||||
_saveItemCommand.ExecuteNonQuery();
|
_saveItemCommand.ExecuteNonQuery();
|
||||||
|
@ -1209,6 +1265,46 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (type == typeof(Person))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (type == typeof(RecordingGroup))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (type == typeof(Channel))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (type == typeof(ManualCollectionsFolder))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (type == typeof(CameraUploadsFolder))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (type == typeof(PlaylistsFolder))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (type == typeof(UserRootFolder))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (type == typeof(PhotoAlbum))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (type == typeof(Season))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (type == typeof(MusicArtist))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_config.Configuration.SkipDeserializationForPrograms)
|
if (_config.Configuration.SkipDeserializationForPrograms)
|
||||||
{
|
{
|
||||||
|
@ -1767,6 +1863,27 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
|
if (query.HasField(ItemFields.ProductionLocations))
|
||||||
|
{
|
||||||
|
if (!reader.IsDBNull(index))
|
||||||
|
{
|
||||||
|
item.ProductionLocations = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reader.IsDBNull(index))
|
||||||
|
{
|
||||||
|
item.ThemeSongIds = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList();
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
|
||||||
|
if (!reader.IsDBNull(index))
|
||||||
|
{
|
||||||
|
item.ThemeVideoIds = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList();
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(item.Tagline))
|
if (string.IsNullOrWhiteSpace(item.Tagline))
|
||||||
{
|
{
|
||||||
var movie = item as Movie;
|
var movie = item as Movie;
|
||||||
|
@ -1776,6 +1893,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == typeof(Person) && item.ProductionLocations.Count == 0)
|
||||||
|
{
|
||||||
|
var person = (Person)item;
|
||||||
|
if (!string.IsNullOrWhiteSpace(person.PlaceOfBirth))
|
||||||
|
{
|
||||||
|
item.ProductionLocations = new List<string> { person.PlaceOfBirth };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -377,6 +377,7 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "Keywords" };
|
ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "Keywords" };
|
||||||
ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ShortOverview" };
|
ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ShortOverview" };
|
||||||
ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ShortOverview" };
|
ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ShortOverview" };
|
||||||
|
ServiceStack.Text.JsConfig<Person>.ExcludePropertyNames = new[] { "PlaceOfBirth" };
|
||||||
|
|
||||||
ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ProviderIds" };
|
ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ProviderIds" };
|
||||||
ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ProviderIds" };
|
ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ProviderIds" };
|
||||||
|
@ -448,6 +449,111 @@ namespace MediaBrowser.Server.Startup.Common
|
||||||
ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ImageInfos" };
|
ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ImageInfos" };
|
||||||
ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ImageInfos" };
|
ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ImageInfos" };
|
||||||
|
|
||||||
|
ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<LiveTvVideoRecording>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<LiveTvAudioRecording>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Audio>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<MusicAlbum>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<MusicArtist>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<MusicGenre>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<MusicVideo>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Playlist>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<AudioPodcast>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<BoxSet>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Episode>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Season>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Book>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<CollectionFolder>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Folder>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Game>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<GameGenre>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<GameSystem>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Genre>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Person>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Photo>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<PhotoAlbum>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Studio>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<UserRootFolder>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<UserView>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Video>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Year>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ProductionLocations" };
|
||||||
|
|
||||||
|
ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<LiveTvVideoRecording>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<LiveTvAudioRecording>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Audio>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<MusicAlbum>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<MusicArtist>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<MusicGenre>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<MusicVideo>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Playlist>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<AudioPodcast>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<BoxSet>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Episode>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Season>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Book>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<CollectionFolder>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Folder>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Game>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<GameGenre>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<GameSystem>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Genre>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Person>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Photo>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<PhotoAlbum>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Studio>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<UserRootFolder>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<UserView>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Video>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Year>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ThemeSongIds" };
|
||||||
|
|
||||||
|
ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<LiveTvVideoRecording>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<LiveTvAudioRecording>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Audio>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<MusicAlbum>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<MusicArtist>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<MusicGenre>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<MusicVideo>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Playlist>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<AudioPodcast>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<BoxSet>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Episode>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Season>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Book>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<CollectionFolder>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Folder>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Game>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<GameGenre>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<GameSystem>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Genre>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Person>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Photo>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<PhotoAlbum>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Studio>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<UserRootFolder>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<UserView>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Video>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Year>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ThemeVideoIds" };
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -505,9 +505,10 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(val))
|
if (!string.IsNullOrWhiteSpace(val))
|
||||||
{
|
{
|
||||||
//var countries = val.Split('/')
|
item.ProductionLocations = val.Split('/')
|
||||||
// .Select(i => i.Trim())
|
.Select(i => i.Trim())
|
||||||
// .Where(i => !string.IsNullOrWhiteSpace(i));
|
.Where(i => !string.IsNullOrWhiteSpace(i))
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
|
||||||
"imdbid",
|
"imdbid",
|
||||||
"imdb_id",
|
"imdb_id",
|
||||||
"plotkeyword",
|
"plotkeyword",
|
||||||
//"country",
|
"country",
|
||||||
"audiodbalbumid",
|
"audiodbalbumid",
|
||||||
"audiodbartistid",
|
"audiodbartistid",
|
||||||
"awardsummary",
|
"awardsummary",
|
||||||
|
@ -723,10 +723,10 @@ namespace MediaBrowser.XbmcMetadata.Savers
|
||||||
writer.WriteElementString("tagline", item.Tagline);
|
writer.WriteElementString("tagline", item.Tagline);
|
||||||
}
|
}
|
||||||
|
|
||||||
//foreach (var country in hasProductionLocations.ProductionLocations)
|
foreach (var country in item.ProductionLocations)
|
||||||
//{
|
{
|
||||||
// writer.WriteElementString("country", country);
|
writer.WriteElementString("country", country);
|
||||||
//}
|
}
|
||||||
|
|
||||||
foreach (var genre in item.Genres)
|
foreach (var genre in item.Genres)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user