audio podcast

This commit is contained in:
Luke Pulverenti 2016-03-19 15:32:37 -04:00
parent 1d2b6329bf
commit db1bf5b1b5
19 changed files with 523 additions and 107 deletions

View File

@ -0,0 +1,102 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Users;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
namespace MediaBrowser.Controller.Channels
{
public class ChannelAudioItem : Audio
{
public ChannelMediaContentType ContentType { get; set; }
public List<ChannelMediaInfo> ChannelMediaSources { get; set; }
public override UnratedItem GetBlockUnratedType()
{
return UnratedItem.ChannelContent;
}
protected override string CreateUserDataKey()
{
return ExternalId;
}
[IgnoreDataMember]
public override bool SupportsLocalMetadata
{
get
{
return false;
}
}
public override bool IsSaveLocalMetadataEnabled()
{
return false;
}
public ChannelAudioItem()
{
ChannelMediaSources = new List<ChannelMediaInfo>();
}
[IgnoreDataMember]
public override LocationType LocationType
{
get
{
if (string.IsNullOrEmpty(Path))
{
return LocationType.Remote;
}
return base.LocationType;
}
}
protected override string GetInternalMetadataPath(string basePath)
{
return System.IO.Path.Combine(basePath, "channels", ChannelId, Id.ToString("N"));
}
public override IEnumerable<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
{
var sources = ChannelManager.GetStaticMediaSources(this, false, CancellationToken.None)
.Result.ToList();
if (sources.Count > 0)
{
return sources;
}
var list = base.GetMediaSources(enablePathSubstitution).ToList();
foreach (var mediaSource in list)
{
if (string.IsNullOrWhiteSpace(mediaSource.Path))
{
mediaSource.Type = MediaSourceType.Placeholder;
}
}
return list;
}
public override bool CanDelete()
{
return false;
}
public override bool IsVisibleStandalone(User user)
{
return IsVisibleStandaloneInternal(user, false) && ChannelVideoItem.IsChannelVisible(this, user);
}
}
}

View File

@ -0,0 +1,90 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Users;
using System;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Channels
{
public class ChannelFolderItem : Folder
{
public ChannelFolderType ChannelFolderType { get; set; }
protected override bool GetBlockUnratedValue(UserPolicy config)
{
// Don't block.
return false;
}
public override UnratedItem GetBlockUnratedType()
{
return UnratedItem.ChannelContent;
}
[IgnoreDataMember]
public override bool SupportsLocalMetadata
{
get
{
return false;
}
}
public override bool IsSaveLocalMetadataEnabled()
{
return false;
}
protected override string CreateUserDataKey()
{
return ExternalId;
}
public override async Task<QueryResult<BaseItem>> GetItems(InternalItemsQuery query)
{
try
{
// Don't blow up here because it could cause parent screens with other content to fail
return await ChannelManager.GetChannelItemsInternal(new ChannelItemQuery
{
ChannelId = ChannelId,
FolderId = Id.ToString("N"),
Limit = query.Limit,
StartIndex = query.StartIndex,
UserId = query.User.Id.ToString("N"),
SortBy = query.SortBy,
SortOrder = query.SortOrder
}, new Progress<double>(), CancellationToken.None);
}
catch
{
// Already logged at lower levels
return new QueryResult<BaseItem>
{
};
}
}
protected override string GetInternalMetadataPath(string basePath)
{
return System.IO.Path.Combine(basePath, "channels", ChannelId, Id.ToString("N"));
}
public override bool CanDelete()
{
return false;
}
public override bool IsVisibleStandalone(User user)
{
return IsVisibleStandaloneInternal(user, false) && ChannelVideoItem.IsChannelVisible(this, user);
}
}
}

View File

@ -0,0 +1,128 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Users;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
namespace MediaBrowser.Controller.Channels
{
public class ChannelVideoItem : Video
{
public ChannelMediaContentType ContentType { get; set; }
public List<ChannelMediaInfo> ChannelMediaSources { get; set; }
protected override string CreateUserDataKey()
{
if (ContentType == ChannelMediaContentType.MovieExtra)
{
var key = this.GetProviderId(MetadataProviders.Imdb) ?? this.GetProviderId(MetadataProviders.Tmdb);
if (!string.IsNullOrWhiteSpace(key))
{
key = key + "-" + ExtraType.ToString().ToLower();
// Make sure different trailers have their own data.
if (RunTimeTicks.HasValue)
{
key += "-" + RunTimeTicks.Value.ToString(CultureInfo.InvariantCulture);
}
return key;
}
}
return ExternalId;
}
public override UnratedItem GetBlockUnratedType()
{
return UnratedItem.ChannelContent;
}
[IgnoreDataMember]
public override bool SupportsLocalMetadata
{
get
{
return false;
}
}
public override bool IsSaveLocalMetadataEnabled()
{
return false;
}
public ChannelVideoItem()
{
ChannelMediaSources = new List<ChannelMediaInfo>();
}
[IgnoreDataMember]
public override LocationType LocationType
{
get
{
if (string.IsNullOrEmpty(Path))
{
return LocationType.Remote;
}
return base.LocationType;
}
}
public override IEnumerable<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
{
var sources = ChannelManager.GetStaticMediaSources(this, false, CancellationToken.None)
.Result.ToList();
if (sources.Count > 0)
{
return sources;
}
var list = base.GetMediaSources(enablePathSubstitution).ToList();
foreach (var mediaSource in list)
{
if (string.IsNullOrWhiteSpace(mediaSource.Path))
{
mediaSource.Type = MediaSourceType.Placeholder;
}
}
return list;
}
protected override string GetInternalMetadataPath(string basePath)
{
return System.IO.Path.Combine(basePath, "channels", ChannelId, Id.ToString("N"));
}
public override bool CanDelete()
{
return false;
}
public override bool IsVisibleStandalone(User user)
{
return IsVisibleStandaloneInternal(user, false) && IsChannelVisible(this, user);
}
internal static bool IsChannelVisible(BaseItem item, User user)
{
var channel = ChannelManager.GetChannel(item.ChannelId);
return channel.IsVisible(user);
}
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Entities.Audio
{
public class AudioPodcast : Audio
{
}
}

View File

@ -117,6 +117,8 @@ namespace MediaBrowser.Controller.Entities
public string[] PresetViews { get; set; } public string[] PresetViews { get; set; }
public SourceType[] SourceTypes { get; set; } public SourceType[] SourceTypes { get; set; }
public SourceType[] ExcludeSourceTypes { get; set; } public SourceType[] ExcludeSourceTypes { get; set; }
public TrailerType[] TrailerTypes { get; set; }
public TrailerType[] ExcludeTrailerTypes { get; set; }
public InternalItemsQuery() public InternalItemsQuery()
{ {
@ -145,6 +147,8 @@ namespace MediaBrowser.Controller.Entities
PresetViews = new string[] { }; PresetViews = new string[] { };
SourceTypes = new SourceType[] { }; SourceTypes = new SourceType[] { };
ExcludeSourceTypes = new SourceType[] { }; ExcludeSourceTypes = new SourceType[] { };
TrailerTypes = new TrailerType[] { };
ExcludeTrailerTypes = new TrailerType[] { };
} }
public InternalItemsQuery(User user) public InternalItemsQuery(User user)

View File

@ -3,8 +3,8 @@ namespace MediaBrowser.Controller.Entities
{ {
public enum SourceType public enum SourceType
{ {
Library = 0, Library = 1,
Channel = 1, Channel = 2,
LiveTV = 2 LiveTV = 3
} }
} }

View File

@ -24,8 +24,11 @@ namespace MediaBrowser.Controller.Entities
Taglines = new List<string>(); Taglines = new List<string>();
Keywords = new List<string>(); Keywords = new List<string>();
ProductionLocations = new List<string>(); ProductionLocations = new List<string>();
TrailerTypes = new List<TrailerType>();
} }
public List<TrailerType> TrailerTypes { get; set; }
public float? Metascore { get; set; } public float? Metascore { get; set; }
public List<MediaUrl> RemoteTrailers { get; set; } public List<MediaUrl> RemoteTrailers { get; set; }
@ -62,20 +65,6 @@ namespace MediaBrowser.Controller.Entities
/// <value>The critic rating summary.</value> /// <value>The critic rating summary.</value>
public string CriticRatingSummary { get; set; } public string CriticRatingSummary { get; set; }
/// <summary>
/// Gets a value indicating whether this instance is local trailer.
/// </summary>
/// <value><c>true</c> if this instance is local trailer; otherwise, <c>false</c>.</value>
[IgnoreDataMember]
public bool IsLocalTrailer
{
get
{
// Local trailers are not part of children
return GetParent() == null;
}
}
protected override string CreateUserDataKey() protected override string CreateUserDataKey()
{ {
var key = Movie.GetMovieUserDataKey(this); var key = Movie.GetMovieUserDataKey(this);
@ -105,7 +94,7 @@ namespace MediaBrowser.Controller.Entities
{ {
var info = GetItemLookupInfo<TrailerInfo>(); var info = GetItemLookupInfo<TrailerInfo>();
info.IsLocalTrailer = IsLocalTrailer; info.IsLocalTrailer = TrailerTypes.Contains(TrailerType.LocalTrailer);
if (!IsInMixedFolder) if (!IsInMixedFolder)
{ {

View File

@ -75,12 +75,15 @@
</Compile> </Compile>
<Compile Include="Activity\IActivityManager.cs" /> <Compile Include="Activity\IActivityManager.cs" />
<Compile Include="Activity\IActivityRepository.cs" /> <Compile Include="Activity\IActivityRepository.cs" />
<Compile Include="Channels\ChannelAudioItem.cs" />
<Compile Include="Channels\ChannelFolderItem.cs" />
<Compile Include="Channels\ChannelItemInfo.cs" /> <Compile Include="Channels\ChannelItemInfo.cs" />
<Compile Include="Channels\ChannelItemResult.cs" /> <Compile Include="Channels\ChannelItemResult.cs" />
<Compile Include="Channels\ChannelItemType.cs" /> <Compile Include="Channels\ChannelItemType.cs" />
<Compile Include="Channels\ChannelMediaInfo.cs" /> <Compile Include="Channels\ChannelMediaInfo.cs" />
<Compile Include="Channels\ChannelParentalRating.cs" /> <Compile Include="Channels\ChannelParentalRating.cs" />
<Compile Include="Channels\ChannelSearchInfo.cs" /> <Compile Include="Channels\ChannelSearchInfo.cs" />
<Compile Include="Channels\ChannelVideoItem.cs" />
<Compile Include="Channels\IChannel.cs" /> <Compile Include="Channels\IChannel.cs" />
<Compile Include="Channels\IChannelManager.cs" /> <Compile Include="Channels\IChannelManager.cs" />
<Compile Include="Channels\Channel.cs" /> <Compile Include="Channels\Channel.cs" />
@ -123,6 +126,7 @@
<Compile Include="Drawing\ImageStream.cs" /> <Compile Include="Drawing\ImageStream.cs" />
<Compile Include="Dto\DtoOptions.cs" /> <Compile Include="Dto\DtoOptions.cs" />
<Compile Include="Dto\IDtoService.cs" /> <Compile Include="Dto\IDtoService.cs" />
<Compile Include="Entities\Audio\AudioPodcast.cs" />
<Compile Include="Entities\Audio\IHasAlbumArtist.cs" /> <Compile Include="Entities\Audio\IHasAlbumArtist.cs" />
<Compile Include="Entities\Audio\IHasMusicGenres.cs" /> <Compile Include="Entities\Audio\IHasMusicGenres.cs" />
<Compile Include="Entities\Book.cs" /> <Compile Include="Entities\Book.cs" />

View File

@ -1,3 +1,5 @@
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers namespace MediaBrowser.Controller.Providers
{ {
public class TrailerInfo : ItemLookupInfo public class TrailerInfo : ItemLookupInfo

View File

@ -44,6 +44,12 @@ namespace MediaBrowser.Model.Dto
/// <value>The etag.</value> /// <value>The etag.</value>
public string Etag { get; set; } public string Etag { get; set; }
/// <summary>
/// Gets or sets the type of the source.
/// </summary>
/// <value>The type of the source.</value>
public string SourceType { get; set; }
/// <summary> /// <summary>
/// Gets or sets the playlist item identifier. /// Gets or sets the playlist item identifier.
/// </summary> /// </summary>

View File

@ -5,6 +5,7 @@ namespace MediaBrowser.Model.Entities
ComingSoonToTheaters = 1, ComingSoonToTheaters = 1,
ComingSoonToDvd = 2, ComingSoonToDvd = 2,
ComingSoonToStreaming = 3, ComingSoonToStreaming = 3,
Archive = 4 Archive = 4,
LocalTrailer = 5
} }
} }

View File

@ -67,6 +67,11 @@ namespace MediaBrowser.Providers.Movies
protected override void MergeData(MetadataResult<Trailer> source, MetadataResult<Trailer> target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings) protected override void MergeData(MetadataResult<Trailer> source, MetadataResult<Trailer> target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
{ {
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings); ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
if (replaceData || target.Item.TrailerTypes.Count == 0)
{
target.Item.TrailerTypes = source.Item.TrailerTypes;
}
} }
} }

View File

@ -424,6 +424,7 @@ namespace MediaBrowser.Server.Implementations.Channels
var parentFolderId = parentFolder.Id; var parentFolderId = parentFolder.Id;
var id = GetInternalChannelId(channelInfo.Name); var id = GetInternalChannelId(channelInfo.Name);
var idString = id.ToString("N");
var path = Channel.GetInternalMetadataPath(_config.ApplicationPaths.InternalMetadataPath, id); var path = Channel.GetInternalMetadataPath(_config.ApplicationPaths.InternalMetadataPath, id);
@ -431,7 +432,6 @@ namespace MediaBrowser.Server.Implementations.Channels
var forceUpdate = false; var forceUpdate = false;
var item = _libraryManager.GetItemById(id) as Channel; var item = _libraryManager.GetItemById(id) as Channel;
var channelId = channelInfo.Name.GetMD5().ToString("N");
if (item == null) if (item == null)
{ {
@ -452,11 +452,11 @@ namespace MediaBrowser.Server.Implementations.Channels
} }
item.Path = path; item.Path = path;
if (!string.Equals(item.ChannelId, channelId, StringComparison.OrdinalIgnoreCase)) if (!string.Equals(item.ChannelId, idString, StringComparison.OrdinalIgnoreCase))
{ {
forceUpdate = true; forceUpdate = true;
} }
item.ChannelId = channelId; item.ChannelId = idString;
if (item.ParentId != parentFolderId) if (item.ParentId != parentFolderId)
{ {
@ -505,7 +505,7 @@ namespace MediaBrowser.Server.Implementations.Channels
public Channel GetChannel(string id) public Channel GetChannel(string id)
{ {
return _libraryManager.GetItemById(new Guid(id)) as Channel; return _libraryManager.GetItemById(id) as Channel;
} }
public IEnumerable<ChannelFeatures> GetAllChannelFeatures() public IEnumerable<ChannelFeatures> GetAllChannelFeatures()
@ -523,6 +523,11 @@ namespace MediaBrowser.Server.Implementations.Channels
public ChannelFeatures GetChannelFeatures(string id) public ChannelFeatures GetChannelFeatures(string id)
{ {
if (string.IsNullOrWhiteSpace(id))
{
throw new ArgumentNullException("id");
}
var channel = GetChannel(id); var channel = GetChannel(id);
var channelProvider = GetChannelProvider(channel); var channelProvider = GetChannelProvider(channel);
@ -1260,9 +1265,16 @@ namespace MediaBrowser.Server.Implementations.Channels
} }
} }
else if (info.MediaType == ChannelMediaType.Audio) else if (info.MediaType == ChannelMediaType.Audio)
{
if (info.ContentType == ChannelMediaContentType.Podcast)
{
item = GetItemById<AudioPodcast>(info.Id, channelProvider.Name, channelProvider.DataVersion, out isNew);
}
else
{ {
item = GetItemById<Audio>(info.Id, channelProvider.Name, channelProvider.DataVersion, out isNew); item = GetItemById<Audio>(info.Id, channelProvider.Name, channelProvider.DataVersion, out isNew);
} }
}
else else
{ {
if (info.ContentType == ChannelMediaContentType.Episode) if (info.ContentType == ChannelMediaContentType.Episode)
@ -1302,6 +1314,16 @@ namespace MediaBrowser.Server.Implementations.Channels
item.Tags = info.Tags; item.Tags = info.Tags;
} }
var trailer = item as Trailer;
if (trailer != null)
{
if (!info.TrailerTypes.SequenceEqual(trailer.TrailerTypes))
{
forceUpdate = true;
}
trailer.TrailerTypes = info.TrailerTypes;
}
item.ChannelId = internalChannelId.ToString("N"); item.ChannelId = internalChannelId.ToString("N");
if (item.ParentId != internalChannelId) if (item.ParentId != internalChannelId)
@ -1384,7 +1406,12 @@ namespace MediaBrowser.Server.Implementations.Channels
internal IChannel GetChannelProvider(Channel channel) internal IChannel GetChannelProvider(Channel channel)
{ {
var result = GetAllChannels().FirstOrDefault(i => string.Equals(i.Name.GetMD5().ToString("N"), channel.ChannelId, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, channel.Name, StringComparison.OrdinalIgnoreCase)); if (channel == null)
{
throw new ArgumentNullException("channel");
}
var result = GetAllChannels().FirstOrDefault(i => string.Equals(GetInternalChannelId(i.Name).ToString("N"), channel.ChannelId, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, channel.Name, StringComparison.OrdinalIgnoreCase));
if (result == null) if (result == null)
{ {
@ -1519,7 +1546,6 @@ namespace MediaBrowser.Server.Implementations.Channels
Progress = new Progress<double>() Progress = new Progress<double>()
}; };
var host = new Uri(source.Path).Host.ToLower();
var channel = GetChannel(item.ChannelId); var channel = GetChannel(item.ChannelId);
var channelProvider = GetChannelProvider(channel); var channelProvider = GetChannelProvider(channel);
var features = channelProvider.GetChannelFeatures(); var features = channelProvider.GetChannelFeatures();

View File

@ -316,6 +316,11 @@ namespace MediaBrowser.Server.Implementations.Dto
ServerId = _appHost.SystemId ServerId = _appHost.SystemId
}; };
if (item.SourceType == SourceType.Channel)
{
dto.SourceType = item.SourceType.ToString();
}
if (fields.Contains(ItemFields.People)) if (fields.Contains(ItemFields.People))
{ {
AttachPeople(dto, item); AttachPeople(dto, item);

View File

@ -24,17 +24,15 @@ namespace MediaBrowser.Server.Implementations.Intros
public class DefaultIntroProvider : IIntroProvider public class DefaultIntroProvider : IIntroProvider
{ {
private readonly ISecurityManager _security; private readonly ISecurityManager _security;
private readonly IChannelManager _channelManager;
private readonly ILocalizationManager _localization; private readonly ILocalizationManager _localization;
private readonly IConfigurationManager _serverConfig; private readonly IConfigurationManager _serverConfig;
private readonly ILibraryManager _libraryManager; private readonly ILibraryManager _libraryManager;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly IMediaSourceManager _mediaSourceManager; private readonly IMediaSourceManager _mediaSourceManager;
public DefaultIntroProvider(ISecurityManager security, IChannelManager channelManager, ILocalizationManager localization, IConfigurationManager serverConfig, ILibraryManager libraryManager, IFileSystem fileSystem, IMediaSourceManager mediaSourceManager) public DefaultIntroProvider(ISecurityManager security, ILocalizationManager localization, IConfigurationManager serverConfig, ILibraryManager libraryManager, IFileSystem fileSystem, IMediaSourceManager mediaSourceManager)
{ {
_security = security; _security = security;
_channelManager = channelManager;
_localization = localization; _localization = localization;
_serverConfig = serverConfig; _serverConfig = serverConfig;
_libraryManager = libraryManager; _libraryManager = libraryManager;
@ -79,44 +77,15 @@ namespace MediaBrowser.Server.Implementations.Intros
AppearsInItemId = item.Id AppearsInItemId = item.Id
}); });
if (config.EnableIntrosFromMoviesInLibrary)
{
var inputItems = _libraryManager.GetItems(new InternalItemsQuery(user)
{
IncludeItemTypes = new[] { typeof(Movie).Name }
}, new string[] { });
var itemsWithTrailers = inputItems
.Where(i =>
{
var hasTrailers = i as IHasTrailers;
if (hasTrailers != null && hasTrailers.LocalTrailerIds.Count > 0)
{
if (i is Movie)
{
return !IsDuplicate(item, i);
}
}
return false;
});
candidates.AddRange(itemsWithTrailers.Select(i => new ItemWithTrailer
{
Item = i,
Type = ItemWithTrailerType.ItemWithTrailer,
User = user,
WatchingItem = item,
WatchingItemPeople = itemPeople,
AllPeople = allPeople,
Random = random,
LibraryManager = _libraryManager
}));
}
var trailerTypes = new List<TrailerType>(); var trailerTypes = new List<TrailerType>();
if (config.EnableIntrosFromMoviesInLibrary)
{
trailerTypes.Add(TrailerType.LocalTrailer);
}
if (IsSupporter)
{
if (config.EnableIntrosFromUpcomingTrailers) if (config.EnableIntrosFromUpcomingTrailers)
{ {
trailerTypes.Add(TrailerType.ComingSoonToTheaters); trailerTypes.Add(TrailerType.ComingSoonToTheaters);
@ -133,22 +102,20 @@ namespace MediaBrowser.Server.Implementations.Intros
{ {
trailerTypes.Add(TrailerType.Archive); trailerTypes.Add(TrailerType.Archive);
} }
}
if (trailerTypes.Count > 0 && IsSupporter) if (trailerTypes.Count > 0)
{ {
var channelTrailers = await _channelManager.GetAllMediaInternal(new AllChannelMediaQuery var trailerResult = _libraryManager.GetItems(new InternalItemsQuery
{ {
ContentTypes = new[] { ChannelMediaContentType.MovieExtra }, IncludeItemTypes = new[] { typeof(Trailer).Name },
ExtraTypes = new[] { ExtraType.Trailer },
UserId = user.Id.ToString("N"),
TrailerTypes = trailerTypes.ToArray() TrailerTypes = trailerTypes.ToArray()
});
}, CancellationToken.None); candidates.AddRange(trailerResult.Items.Select(i => new ItemWithTrailer
candidates.AddRange(channelTrailers.Items.Select(i => new ItemWithTrailer
{ {
Item = i, Item = i,
Type = ItemWithTrailerType.ChannelTrailer, Type = i.SourceType == SourceType.Channel ? ItemWithTrailerType.ChannelTrailer : ItemWithTrailerType.ItemWithTrailer,
User = user, User = user,
WatchingItem = item, WatchingItem = item,
WatchingItemPeople = itemPeople, WatchingItemPeople = itemPeople,
@ -556,7 +523,6 @@ namespace MediaBrowser.Server.Implementations.Intros
internal enum ItemWithTrailerType internal enum ItemWithTrailerType
{ {
LibraryTrailer,
ChannelTrailer, ChannelTrailer,
ItemWithTrailer ItemWithTrailer
} }

View File

@ -40,8 +40,10 @@ using CommonIO;
using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Library; using MediaBrowser.Model.Library;
using MediaBrowser.Model.Net; using MediaBrowser.Model.Net;
using MediaBrowser.Server.Implementations.Library.Resolvers;
using MoreLinq; using MoreLinq;
using SortOrder = MediaBrowser.Model.Entities.SortOrder; using SortOrder = MediaBrowser.Model.Entities.SortOrder;
using VideoResolver = MediaBrowser.Naming.Video.VideoResolver;
namespace MediaBrowser.Server.Implementations.Library namespace MediaBrowser.Server.Implementations.Library
{ {
@ -454,10 +456,11 @@ namespace MediaBrowser.Server.Implementations.Library
/// Resolves the item. /// Resolves the item.
/// </summary> /// </summary>
/// <param name="args">The args.</param> /// <param name="args">The args.</param>
/// <param name="resolvers">The resolvers.</param>
/// <returns>BaseItem.</returns> /// <returns>BaseItem.</returns>
private BaseItem ResolveItem(ItemResolveArgs args) private BaseItem ResolveItem(ItemResolveArgs args, IItemResolver[] resolvers)
{ {
var item = EntityResolvers.Select(r => Resolve(args, r)) var item = (resolvers ?? EntityResolvers).Select(r => Resolve(args, r))
.FirstOrDefault(i => i != null); .FirstOrDefault(i => i != null);
if (item != null) if (item != null)
@ -556,10 +559,10 @@ namespace MediaBrowser.Server.Implementations.Library
public BaseItem ResolvePath(FileSystemMetadata fileInfo, public BaseItem ResolvePath(FileSystemMetadata fileInfo,
Folder parent = null) Folder parent = null)
{ {
return ResolvePath(fileInfo, new DirectoryService(_logger, _fileSystem), parent); return ResolvePath(fileInfo, new DirectoryService(_logger, _fileSystem), null, parent);
} }
private BaseItem ResolvePath(FileSystemMetadata fileInfo, IDirectoryService directoryService, Folder parent = null, string collectionType = null) private BaseItem ResolvePath(FileSystemMetadata fileInfo, IDirectoryService directoryService, IItemResolver[] resolvers, Folder parent = null, string collectionType = null)
{ {
if (fileInfo == null) if (fileInfo == null)
{ {
@ -615,7 +618,7 @@ namespace MediaBrowser.Server.Implementations.Library
return null; return null;
} }
return ResolveItem(args); return ResolveItem(args, resolvers);
} }
public bool IgnoreFile(FileSystemMetadata file, BaseItem parent) public bool IgnoreFile(FileSystemMetadata file, BaseItem parent)
@ -657,12 +660,19 @@ namespace MediaBrowser.Server.Implementations.Library
} }
public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, Folder parent, string collectionType) public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, Folder parent, string collectionType)
{
return ResolvePaths(files, directoryService, parent, collectionType, EntityResolvers);
}
public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, Folder parent, string collectionType, IItemResolver[] resolvers)
{ {
var fileList = files.Where(i => !IgnoreFile(i, parent)).ToList(); var fileList = files.Where(i => !IgnoreFile(i, parent)).ToList();
if (parent != null) if (parent != null)
{ {
foreach (var resolver in MultiItemResolvers) var multiItemResolvers = resolvers == null ? MultiItemResolvers : resolvers.OfType<IMultiItemResolver>().ToArray();
foreach (var resolver in multiItemResolvers)
{ {
var result = resolver.ResolveMultiple(parent, fileList, collectionType, directoryService); var result = resolver.ResolveMultiple(parent, fileList, collectionType, directoryService);
@ -675,22 +685,22 @@ namespace MediaBrowser.Server.Implementations.Library
{ {
ResolverHelper.SetInitialItemValues(item, parent, _fileSystem, this, directoryService); ResolverHelper.SetInitialItemValues(item, parent, _fileSystem, this, directoryService);
} }
items.AddRange(ResolveFileList(result.ExtraFiles, directoryService, parent, collectionType)); items.AddRange(ResolveFileList(result.ExtraFiles, directoryService, parent, collectionType, resolvers));
return items; return items;
} }
} }
} }
return ResolveFileList(fileList, directoryService, parent, collectionType); return ResolveFileList(fileList, directoryService, parent, collectionType, resolvers);
} }
private IEnumerable<BaseItem> ResolveFileList(IEnumerable<FileSystemMetadata> fileList, IDirectoryService directoryService, Folder parent, string collectionType) private IEnumerable<BaseItem> ResolveFileList(IEnumerable<FileSystemMetadata> fileList, IDirectoryService directoryService, Folder parent, string collectionType, IItemResolver[] resolvers)
{ {
return fileList.Select(f => return fileList.Select(f =>
{ {
try try
{ {
return ResolvePath(f, directoryService, parent, collectionType); return ResolvePath(f, directoryService, resolvers, parent, collectionType);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -2306,12 +2316,17 @@ namespace MediaBrowser.Server.Implementations.Library
files.AddRange(currentVideo.Extras.Where(i => string.Equals(i.ExtraType, "trailer", StringComparison.OrdinalIgnoreCase)).Select(i => _fileSystem.GetFileInfo(i.Path))); files.AddRange(currentVideo.Extras.Where(i => string.Equals(i.ExtraType, "trailer", StringComparison.OrdinalIgnoreCase)).Select(i => _fileSystem.GetFileInfo(i.Path)));
} }
return ResolvePaths(files, directoryService, null, null) var resolvers = new IItemResolver[]
.OfType<Video>() {
new GenericVideoResolver<Trailer>(this)
};
return ResolvePaths(files, directoryService, null, null, resolvers)
.OfType<Trailer>()
.Select(video => .Select(video =>
{ {
// Try to retrieve it from the db. If we don't find it, use the resolved version // Try to retrieve it from the db. If we don't find it, use the resolved version
var dbItem = GetItemById(video.Id) as Video; var dbItem = GetItemById(video.Id) as Trailer;
if (dbItem != null) if (dbItem != null)
{ {

View File

@ -31,7 +31,10 @@ namespace MediaBrowser.Server.Implementations.Library
var trailerResult = _libraryManager.GetItems(new InternalItemsQuery var trailerResult = _libraryManager.GetItems(new InternalItemsQuery
{ {
IncludeItemTypes = new[] { typeof(Trailer).Name }, IncludeItemTypes = new[] { typeof(Trailer).Name },
//IsLocalTrailer = false ExcludeTrailerTypes = new[]
{
TrailerType.LocalTrailer
}
}); });
var trailers = trailerResult.Items; var trailers = trailerResult.Items;

View File

@ -34,4 +34,12 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
get { return ResolverPriority.Last; } get { return ResolverPriority.Last; }
} }
} }
public class GenericVideoResolver<T> : BaseVideoResolver<T>
where T : Video, new ()
{
public GenericVideoResolver(ILibraryManager libraryManager) : base(libraryManager)
{
}
}
} }

View File

@ -224,6 +224,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
_connection.AddColumn(Logger, "TypedBaseItems", "TopParentId", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "TopParentId", "Text");
_connection.AddColumn(Logger, "TypedBaseItems", "IsItemByName", "BIT"); _connection.AddColumn(Logger, "TypedBaseItems", "IsItemByName", "BIT");
_connection.AddColumn(Logger, "TypedBaseItems", "SourceType", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "SourceType", "Text");
_connection.AddColumn(Logger, "TypedBaseItems", "TrailerTypes", "Text");
PrepareStatements(); PrepareStatements();
@ -355,7 +356,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
"LockedFields", "LockedFields",
"Studios", "Studios",
"Tags", "Tags",
"SourceType" "SourceType",
"TrailerTypes"
}; };
private readonly string[] _mediaStreamSaveColumns = private readonly string[] _mediaStreamSaveColumns =
@ -456,7 +458,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
"UnratedType", "UnratedType",
"TopParentId", "TopParentId",
"IsItemByName", "IsItemByName",
"SourceType" "SourceType",
"TrailerTypes"
}; };
_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 (";
@ -752,6 +755,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
_saveItemCommand.GetParameter(index++).Value = item.SourceType.ToString(); _saveItemCommand.GetParameter(index++).Value = item.SourceType.ToString();
var trailer = item as Trailer;
if (trailer != null)
{
_saveItemCommand.GetParameter(index++).Value = string.Join("|", trailer.TrailerTypes.Select(i => i.ToString()).ToArray());
}
else
{
_saveItemCommand.GetParameter(index++).Value = null;
}
_saveItemCommand.Transaction = transaction; _saveItemCommand.Transaction = transaction;
_saveItemCommand.ExecuteNonQuery(); _saveItemCommand.ExecuteNonQuery();
@ -1119,6 +1132,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
item.SourceType = (SourceType)Enum.Parse(typeof(SourceType), reader.GetString(49), true); item.SourceType = (SourceType)Enum.Parse(typeof(SourceType), reader.GetString(49), true);
} }
var trailer = item as Trailer;
if (trailer != null)
{
if (!reader.IsDBNull(50))
{
trailer.TrailerTypes = reader.GetString(50).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => (TrailerType)Enum.Parse(typeof(TrailerType), i, true)).ToList();
}
}
return item; return item;
} }
@ -1903,6 +1925,34 @@ namespace MediaBrowser.Server.Implementations.Persistence
whereClauses.Add(string.Format("SourceType not in ({0})", inClause)); whereClauses.Add(string.Format("SourceType not in ({0})", inClause));
} }
if (query.TrailerTypes.Length > 0)
{
var clauses = new List<string>();
var index = 0;
foreach (var type in query.TrailerTypes)
{
clauses.Add("TrailerTypes like @TrailerTypes" + index);
cmd.Parameters.Add(cmd, "@TrailerTypes" + index, DbType.String).Value = "%" + type + "%";
index++;
}
var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
whereClauses.Add(clause);
}
if (query.ExcludeTrailerTypes.Length > 0)
{
var clauses = new List<string>();
var index = 0;
foreach (var type in query.ExcludeTrailerTypes)
{
clauses.Add("TrailerTypes not like @TrailerTypes" + index);
cmd.Parameters.Add(cmd, "@TrailerTypes" + index, DbType.String).Value = "%" + type + "%";
index++;
}
var clause = "(" + string.Join(" AND ", clauses.ToArray()) + ")";
whereClauses.Add(clause);
}
if (query.IsAiring.HasValue) if (query.IsAiring.HasValue)
{ {
if (query.IsAiring.Value) if (query.IsAiring.Value)