Merge pull request #2216 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-10-09 03:20:21 -04:00 committed by GitHub
commit dbf1e2c27e
53 changed files with 645 additions and 414 deletions

View File

@ -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)

View File

@ -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)
{ {

View File

@ -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);
} }
} }

View File

@ -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;

View File

@ -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]

View File

@ -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();

View File

@ -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>

View File

@ -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>

View File

@ -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; }
}
}

View File

@ -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:

View File

@ -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>();
} }

View File

@ -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);

View File

@ -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; }

View File

@ -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)

View File

@ -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]

View File

@ -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&lt;IEnumerable&lt;MediaSourceInfo&gt;&gt;.</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&lt;IEnumerable&lt;MediaSourceInfo&gt;&gt;.</returns>
Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(string id, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Adds the information to recording dto. /// Adds the information to recording dto.

View File

@ -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; }

View File

@ -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)

View File

@ -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)

View File

@ -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" />

View File

@ -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))

View File

@ -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)

View File

@ -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();

View File

@ -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>");

View File

@ -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()
{ {

View File

@ -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)

View File

@ -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>

View File

@ -7,7 +7,6 @@ namespace MediaBrowser.Model.LiveTv
Scheduled, Scheduled,
InProgress, InProgress,
Completed, Completed,
Aborted,
Cancelled, Cancelled,
ConflictedOk, ConflictedOk,
ConflictedNotOk, ConflictedNotOk,

View File

@ -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

View File

@ -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);

View File

@ -154,8 +154,6 @@
/// </summary> /// </summary>
People, People,
PlaceOfBirth,
/// <summary> /// <summary>
/// The production locations /// The production locations
/// </summary> /// </summary>

View File

@ -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;

View File

@ -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));

View File

@ -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;
} }

View File

@ -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;
} }
} }

View File

@ -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;

View File

@ -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)

View File

@ -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
{
}
}
} }
} }

View File

@ -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)
{ {

View File

@ -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)
{ {

View File

@ -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)
{ {

View File

@ -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();

View File

@ -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);

View File

@ -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;
} }
} }
} }

View File

@ -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)
};
}
} }
} }
} }

View File

@ -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; }
} }
} }

View File

@ -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;
} }

View File

@ -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;

View File

@ -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);
} }
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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)
{ {