mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-07-19 12:44:19 +01:00
Update to 3.5.2 and .net core 2.1
This commit is contained in:
@@ -1,99 +0,0 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Channels;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Progress;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public class Channel : Folder
|
||||
{
|
||||
public override bool IsVisible(User user)
|
||||
{
|
||||
if (user.Policy.BlockedChannels != null)
|
||||
{
|
||||
if (user.Policy.BlockedChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!user.Policy.EnableAllChannels && !user.Policy.EnabledChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return base.IsVisible(user);
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsInheritedParentImages
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override SourceType SourceType
|
||||
{
|
||||
get { return SourceType.Channel; }
|
||||
}
|
||||
|
||||
protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Don't blow up here because it could cause parent screens with other content to fail
|
||||
return ChannelManager.GetChannelItemsInternal(new ChannelItemQuery
|
||||
{
|
||||
ChannelId = Id.ToString("N"),
|
||||
Limit = query.Limit,
|
||||
StartIndex = query.StartIndex,
|
||||
UserId = query.User.Id.ToString("N"),
|
||||
OrderBy = query.OrderBy
|
||||
|
||||
}, new SimpleProgress<double>(), CancellationToken.None).Result;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Already logged at lower levels
|
||||
return new QueryResult<BaseItem>();
|
||||
}
|
||||
}
|
||||
|
||||
protected override string GetInternalMetadataPath(string basePath)
|
||||
{
|
||||
return GetInternalMetadataPath(basePath, Id);
|
||||
}
|
||||
|
||||
public static string GetInternalMetadataPath(string basePath, Guid id)
|
||||
{
|
||||
return System.IO.Path.Combine(basePath, "channels", id.ToString("N"), "metadata");
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool IsAllowTagFilterEnforced()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static bool IsChannelVisible(BaseItem channelItem, User user)
|
||||
{
|
||||
var channel = ChannelManager.GetChannel(channelItem.ChannelId);
|
||||
|
||||
return channel.IsVisible(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Channels;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public class ChannelItemInfo : IHasProviderIds
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string SeriesName { get; set; }
|
||||
|
||||
public string Id { get; set; }
|
||||
|
||||
public ChannelItemType Type { get; set; }
|
||||
|
||||
public string OfficialRating { get; set; }
|
||||
|
||||
public string Overview { get; set; }
|
||||
|
||||
public List<string> Genres { get; set; }
|
||||
public List<string> Studios { get; set; }
|
||||
public List<string> Tags { get; set; }
|
||||
|
||||
public List<PersonInfo> People { get; set; }
|
||||
|
||||
public float? CommunityRating { get; set; }
|
||||
|
||||
public long? RunTimeTicks { get; set; }
|
||||
|
||||
public string ImageUrl { get; set; }
|
||||
|
||||
public ChannelMediaType MediaType { get; set; }
|
||||
public ChannelFolderType FolderType { get; set; }
|
||||
|
||||
public ChannelMediaContentType ContentType { get; set; }
|
||||
public ExtraType ExtraType { get; set; }
|
||||
public List<TrailerType> TrailerTypes { get; set; }
|
||||
|
||||
public Dictionary<string, string> ProviderIds { get; set; }
|
||||
|
||||
public DateTime? PremiereDate { get; set; }
|
||||
public int? ProductionYear { get; set; }
|
||||
|
||||
public DateTime? DateCreated { get; set; }
|
||||
|
||||
public int? IndexNumber { get; set; }
|
||||
public int? ParentIndexNumber { get; set; }
|
||||
|
||||
public List<ChannelMediaInfo> MediaSources { get; set; }
|
||||
|
||||
public bool IsInfiniteStream { get; set; }
|
||||
|
||||
public string HomePageUrl { get; set; }
|
||||
|
||||
public List<string> Artists { get; set; }
|
||||
|
||||
public List<string> AlbumArtists { get; set; }
|
||||
|
||||
public ChannelItemInfo()
|
||||
{
|
||||
MediaSources = new List<ChannelMediaInfo>();
|
||||
TrailerTypes = new List<TrailerType>();
|
||||
Genres = new List<string>();
|
||||
Studios = new List<string>();
|
||||
People = new List<PersonInfo>();
|
||||
Tags = new List<string>();
|
||||
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
Artists = new List<string>();
|
||||
AlbumArtists = new List<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public class ChannelItemResult
|
||||
{
|
||||
public List<ChannelItemInfo> Items { get; set; }
|
||||
|
||||
public int? TotalRecordCount { get; set; }
|
||||
|
||||
public ChannelItemResult()
|
||||
{
|
||||
Items = new List<ChannelItemInfo>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public enum ChannelItemType
|
||||
{
|
||||
Media = 0,
|
||||
|
||||
Folder = 1
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public class ChannelMediaInfo
|
||||
{
|
||||
public string Path { get; set; }
|
||||
|
||||
public Dictionary<string, string> RequiredHttpHeaders { get; set; }
|
||||
|
||||
public string Container { get; set; }
|
||||
public string AudioCodec { get; set; }
|
||||
public string VideoCodec { get; set; }
|
||||
|
||||
public int? AudioBitrate { get; set; }
|
||||
public int? VideoBitrate { get; set; }
|
||||
public int? Width { get; set; }
|
||||
public int? Height { get; set; }
|
||||
public int? AudioChannels { get; set; }
|
||||
public int? AudioSampleRate { get; set; }
|
||||
|
||||
public string VideoProfile { get; set; }
|
||||
public float? VideoLevel { get; set; }
|
||||
public float? Framerate { get; set; }
|
||||
|
||||
public bool? IsAnamorphic { get; set; }
|
||||
|
||||
public MediaProtocol Protocol { get; set; }
|
||||
|
||||
public long? RunTimeTicks { get; set; }
|
||||
|
||||
public string Id { get; set; }
|
||||
|
||||
public bool ReadAtNativeFramerate { get; set; }
|
||||
public bool SupportsDirectPlay { get; set; }
|
||||
|
||||
public ChannelMediaInfo()
|
||||
{
|
||||
RequiredHttpHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
// This is most common
|
||||
Protocol = MediaProtocol.Http;
|
||||
SupportsDirectPlay = true;
|
||||
}
|
||||
|
||||
public MediaSourceInfo ToMediaSource(Guid itemId)
|
||||
{
|
||||
var id = string.IsNullOrWhiteSpace(Path) ?
|
||||
itemId.ToString("N") :
|
||||
Path.GetMD5().ToString("N");
|
||||
|
||||
var source = new MediaSourceInfo
|
||||
{
|
||||
MediaStreams = GetMediaStreams(this).ToList(),
|
||||
|
||||
Container = Container,
|
||||
Protocol = Protocol,
|
||||
Path = Path,
|
||||
RequiredHttpHeaders = RequiredHttpHeaders,
|
||||
RunTimeTicks = RunTimeTicks,
|
||||
Name = id,
|
||||
Id = id,
|
||||
ReadAtNativeFramerate = ReadAtNativeFramerate,
|
||||
SupportsDirectStream = Protocol == MediaProtocol.Http && !string.IsNullOrWhiteSpace(Container) && !string.Equals(Container, "hls", StringComparison.OrdinalIgnoreCase),
|
||||
SupportsDirectPlay = SupportsDirectPlay,
|
||||
IsRemote = true
|
||||
};
|
||||
|
||||
source.InferTotalBitrate();
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
private IEnumerable<MediaStream> GetMediaStreams(ChannelMediaInfo info)
|
||||
{
|
||||
var list = new List<MediaStream>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(info.VideoCodec))
|
||||
{
|
||||
list.Add(new MediaStream
|
||||
{
|
||||
Type = MediaStreamType.Video,
|
||||
Width = info.Width,
|
||||
RealFrameRate = info.Framerate,
|
||||
Profile = info.VideoProfile,
|
||||
Level = info.VideoLevel,
|
||||
Index = -1,
|
||||
Height = info.Height,
|
||||
Codec = info.VideoCodec,
|
||||
BitRate = info.VideoBitrate,
|
||||
AverageFrameRate = info.Framerate
|
||||
});
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(info.AudioCodec))
|
||||
{
|
||||
list.Add(new MediaStream
|
||||
{
|
||||
Type = MediaStreamType.Audio,
|
||||
Index = -1,
|
||||
Codec = info.AudioCodec,
|
||||
BitRate = info.AudioBitrate,
|
||||
Channels = info.AudioChannels,
|
||||
SampleRate = info.AudioSampleRate
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public enum ChannelParentalRating
|
||||
{
|
||||
GeneralAudience = 0,
|
||||
|
||||
UsPG = 1,
|
||||
|
||||
UsPG13 = 2,
|
||||
|
||||
UsR = 3,
|
||||
|
||||
Adult = 4
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public class ChannelSearchInfo
|
||||
{
|
||||
public string SearchTerm { get; set; }
|
||||
|
||||
public string UserId { get; set; }
|
||||
}
|
||||
|
||||
public class ChannelLatestMediaSearch
|
||||
{
|
||||
public string UserId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public interface IChannel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description.
|
||||
/// </summary>
|
||||
/// <value>The description.</value>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data version.
|
||||
/// </summary>
|
||||
/// <value>The data version.</value>
|
||||
string DataVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the home page URL.
|
||||
/// </summary>
|
||||
/// <value>The home page URL.</value>
|
||||
string HomePageUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parental rating.
|
||||
/// </summary>
|
||||
/// <value>The parental rating.</value>
|
||||
ChannelParentalRating ParentalRating { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel information.
|
||||
/// </summary>
|
||||
/// <returns>ChannelFeatures.</returns>
|
||||
InternalChannelFeatures GetChannelFeatures();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [is enabled for] [the specified user].
|
||||
/// </summary>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <returns><c>true</c> if [is enabled for] [the specified user]; otherwise, <c>false</c>.</returns>
|
||||
bool IsEnabledFor(string userId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel items.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{IEnumerable{ChannelItem}}.</returns>
|
||||
Task<ChannelItemResult> GetChannelItems(InternalChannelItemQuery query, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel image.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{DynamicImageInfo}.</returns>
|
||||
Task<DynamicImageResponse> GetChannelImage(ImageType type, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the supported channel images.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{ImageType}.</returns>
|
||||
IEnumerable<ImageType> GetSupportedChannelImages();
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
using System;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Channels;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public interface IChannelManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the parts.
|
||||
/// </summary>
|
||||
/// <param name="channels">The channels.</param>
|
||||
void AddParts(IEnumerable<IChannel> channels);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel features.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>ChannelFeatures.</returns>
|
||||
ChannelFeatures GetChannelFeatures(string id);
|
||||
|
||||
bool SupportsSync(string channelId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all channel features.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{ChannelFeatures}.</returns>
|
||||
ChannelFeatures[] GetAllChannelFeatures();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>Channel.</returns>
|
||||
Channel GetChannel(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channels internal.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task<QueryResult<Channel>>.</returns>
|
||||
Task<QueryResult<Channel>> GetChannelsInternal(ChannelQuery query, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channels.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{QueryResult{BaseItemDto}}.</returns>
|
||||
Task<QueryResult<BaseItemDto>> GetChannels(ChannelQuery query, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all media internal.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task<QueryResult<BaseItem>>.</returns>
|
||||
Task<QueryResult<BaseItem>> GetAllMediaInternal(AllChannelMediaQuery query, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all media.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{QueryResult{BaseItemDto}}.</returns>
|
||||
Task<QueryResult<BaseItemDto>> GetAllMedia(AllChannelMediaQuery query, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the latest media.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{QueryResult{BaseItemDto}}.</returns>
|
||||
Task<QueryResult<BaseItemDto>> GetLatestChannelItems(AllChannelMediaQuery query, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the latest channel items internal.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task<QueryResult<BaseItem>>.</returns>
|
||||
Task<QueryResult<BaseItem>> GetLatestChannelItemsInternal(AllChannelMediaQuery query, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel items.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{QueryResult{BaseItemDto}}.</returns>
|
||||
Task<QueryResult<BaseItemDto>> GetChannelItems(ChannelItemQuery query, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel items internal.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task<QueryResult<BaseItem>>.</returns>
|
||||
Task<QueryResult<BaseItem>> GetChannelItemsInternal(ChannelItemQuery query, IProgress<double> progress, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel item media sources.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{IEnumerable{MediaSourceInfo}}.</returns>
|
||||
IEnumerable<MediaSourceInfo> GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel folder.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>BaseItemDto.</returns>
|
||||
Folder GetInternalChannelFolder(CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel folder.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
BaseItemDto GetChannelFolder(string userId, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public interface IHasCacheKey
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the cache key.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
string GetCacheKey(string userId);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public interface IIndexableChannel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets all media.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{ChannelItemResult}.</returns>
|
||||
Task<ChannelItemResult> GetAllMedia(InternalAllChannelMediaQuery query, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public interface IRequiresMediaInfoCallback
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the channel item media information.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{IEnumerable{ChannelMediaInfo}}.</returns>
|
||||
Task<IEnumerable<ChannelMediaInfo>> GetChannelItemMediaInfo(string id, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public interface ISearchableChannel
|
||||
{
|
||||
/// <summary>
|
||||
/// Searches the specified search term.
|
||||
/// </summary>
|
||||
/// <param name="searchInfo">The search information.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{IEnumerable{ChannelItemInfo}}.</returns>
|
||||
Task<IEnumerable<ChannelItemInfo>> Search(ChannelSearchInfo searchInfo, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
public interface ISupportsLatestMedia
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the latest media.
|
||||
/// </summary>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{IEnumerable{ChannelItemInfo}}.</returns>
|
||||
Task<IEnumerable<ChannelItemInfo>> GetLatestMedia(ChannelLatestMediaSearch request, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using MediaBrowser.Model.Channels;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public class InternalAllChannelMediaQuery
|
||||
{
|
||||
public string UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content types.
|
||||
/// </summary>
|
||||
/// <value>The content types.</value>
|
||||
public ChannelMediaContentType[] ContentTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the extra types.
|
||||
/// </summary>
|
||||
/// <value>The extra types.</value>
|
||||
public ExtraType[] ExtraTypes { get; set; }
|
||||
public TrailerType[] TrailerTypes { get; set; }
|
||||
|
||||
public InternalAllChannelMediaQuery()
|
||||
{
|
||||
ContentTypes = new ChannelMediaContentType[] { };
|
||||
ExtraTypes = new ExtraType[] { };
|
||||
TrailerTypes = new TrailerType[] { };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using System;
|
||||
using MediaBrowser.Model.Channels;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public class InternalChannelFeatures
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the media types.
|
||||
/// </summary>
|
||||
/// <value>The media types.</value>
|
||||
public List<ChannelMediaType> MediaTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content types.
|
||||
/// </summary>
|
||||
/// <value>The content types.</value>
|
||||
public List<ChannelMediaContentType> ContentTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the maximum number of records the channel allows retrieving at a time
|
||||
/// </summary>
|
||||
public int? MaxPageSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the default sort orders.
|
||||
/// </summary>
|
||||
/// <value>The default sort orders.</value>
|
||||
public List<ChannelItemSortField> DefaultSortFields { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if a sort ascending/descending toggle is supported or not.
|
||||
/// </summary>
|
||||
public bool SupportsSortOrderToggle { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the automatic refresh levels.
|
||||
/// </summary>
|
||||
/// <value>The automatic refresh levels.</value>
|
||||
public int? AutoRefreshLevels { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the daily download limit.
|
||||
/// </summary>
|
||||
/// <value>The daily download limit.</value>
|
||||
public int? DailyDownloadLimit { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [supports downloading].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [supports downloading]; otherwise, <c>false</c>.</value>
|
||||
public bool SupportsContentDownloading { get; set; }
|
||||
|
||||
public InternalChannelFeatures()
|
||||
{
|
||||
MediaTypes = new List<ChannelMediaType>();
|
||||
ContentTypes = new List<ChannelMediaContentType>();
|
||||
|
||||
DefaultSortFields = new List<ChannelItemSortField>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using MediaBrowser.Model.Channels;
|
||||
|
||||
namespace MediaBrowser.Controller.Channels
|
||||
{
|
||||
public class InternalChannelItemQuery
|
||||
{
|
||||
public string FolderId { get; set; }
|
||||
|
||||
public string UserId { get; set; }
|
||||
|
||||
public int? StartIndex { get; set; }
|
||||
|
||||
public int? Limit { get; set; }
|
||||
|
||||
public ChannelItemSortField? SortBy { get; set; }
|
||||
|
||||
public bool SortDescending { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Chapters
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IChapterManager
|
||||
/// </summary>
|
||||
public interface IChapterManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the chapters.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item identifier.</param>
|
||||
/// <returns>List{ChapterInfo}.</returns>
|
||||
List<ChapterInfo> GetChapters(string itemId);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the chapters.
|
||||
/// </summary>
|
||||
void SaveChapters(string itemId, List<ChapterInfo> chapters);
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Collections
|
||||
{
|
||||
public class CollectionCreationOptions : IHasProviderIds
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public Guid? ParentId { get; set; }
|
||||
|
||||
public bool IsLocked { get; set; }
|
||||
|
||||
public Dictionary<string, string> ProviderIds { get; set; }
|
||||
|
||||
public string[] ItemIdList { get; set; }
|
||||
public string[] UserIds { get; set; }
|
||||
|
||||
public CollectionCreationOptions()
|
||||
{
|
||||
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
ItemIdList = new string[] { };
|
||||
UserIds = new string[] { };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Collections
|
||||
{
|
||||
public class CollectionCreatedEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the collection.
|
||||
/// </summary>
|
||||
/// <value>The collection.</value>
|
||||
public BoxSet Collection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the options.
|
||||
/// </summary>
|
||||
/// <value>The options.</value>
|
||||
public CollectionCreationOptions Options { get; set; }
|
||||
}
|
||||
|
||||
public class CollectionModifiedEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the collection.
|
||||
/// </summary>
|
||||
/// <value>The collection.</value>
|
||||
public BoxSet Collection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the items changed.
|
||||
/// </summary>
|
||||
/// <value>The items changed.</value>
|
||||
public List<BaseItem> ItemsChanged { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Collections
|
||||
{
|
||||
public interface ICollectionManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs when [collection created].
|
||||
/// </summary>
|
||||
event EventHandler<CollectionCreatedEventArgs> CollectionCreated;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [items added to collection].
|
||||
/// </summary>
|
||||
event EventHandler<CollectionModifiedEventArgs> ItemsAddedToCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [items removed from collection].
|
||||
/// </summary>
|
||||
event EventHandler<CollectionModifiedEventArgs> ItemsRemovedFromCollection;
|
||||
|
||||
/// <summary>
|
||||
/// Creates the collection.
|
||||
/// </summary>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task<BoxSet> CreateCollection(CollectionCreationOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Adds to collection.
|
||||
/// </summary>
|
||||
/// <param name="collectionId">The collection identifier.</param>
|
||||
/// <param name="itemIds">The item ids.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task AddToCollection(Guid collectionId, IEnumerable<string> itemIds);
|
||||
|
||||
/// <summary>
|
||||
/// Removes from collection.
|
||||
/// </summary>
|
||||
/// <param name="collectionId">The collection identifier.</param>
|
||||
/// <param name="itemIds">The item ids.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task RemoveFromCollection(Guid collectionId, IEnumerable<string> itemIds);
|
||||
|
||||
Task AddToCollection(Guid collectionId, IEnumerable<Guid> itemIds);
|
||||
Task RemoveFromCollection(Guid collectionId, IEnumerable<Guid> itemIds);
|
||||
|
||||
/// <summary>
|
||||
/// Collapses the items within box sets.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
IEnumerable<BaseItem> CollapseItemsWithinBoxSets(IEnumerable<BaseItem> items, User user);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collections folder.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <returns>Folder.</returns>
|
||||
Folder GetCollectionsFolder(string userId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collections.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable<BoxSet>.</returns>
|
||||
IEnumerable<BoxSet> GetCollections(User user);
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Collections
|
||||
{
|
||||
public class ManualCollectionsFolder : BasePluginFolder, IHiddenFromDisplay
|
||||
{
|
||||
public ManualCollectionsFolder()
|
||||
{
|
||||
Name = "Collections";
|
||||
}
|
||||
|
||||
public override bool IsHidden
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsInheritedParentImages
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsHiddenFromUser(User user)
|
||||
{
|
||||
return !ConfigurationManager.Configuration.DisplayCollectionsView;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override string CollectionType
|
||||
{
|
||||
get { return Model.Entities.CollectionType.BoxSets; }
|
||||
}
|
||||
|
||||
public override string GetClientTypeName()
|
||||
{
|
||||
return typeof(CollectionFolder).Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.Controller.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IServerConfigurationManager
|
||||
/// </summary>
|
||||
public interface IServerConfigurationManager : IConfigurationManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the application paths.
|
||||
/// </summary>
|
||||
/// <value>The application paths.</value>
|
||||
IServerApplicationPaths ApplicationPaths { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the configuration.
|
||||
/// </summary>
|
||||
/// <value>The configuration.</value>
|
||||
ServerConfiguration Configuration { get; }
|
||||
|
||||
bool SetOptimalValues();
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using MediaBrowser.Model.Connect;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Controller.Connect
|
||||
{
|
||||
public class ConnectSupporterSummary
|
||||
{
|
||||
public int MaxUsers { get; set; }
|
||||
public List<ConnectUser> Users { get; set; }
|
||||
public List<UserDto> EligibleUsers { get; set; }
|
||||
|
||||
public ConnectSupporterSummary()
|
||||
{
|
||||
Users = new List<ConnectUser>();
|
||||
EligibleUsers = new List<UserDto>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Connect;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Connect
|
||||
{
|
||||
public interface IConnectManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the wan API address.
|
||||
/// </summary>
|
||||
/// <value>The wan API address.</value>
|
||||
string WanApiAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Links the user.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <param name="connectUsername">The connect username.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task<UserLinkResult> LinkUser(string userId, string connectUsername);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the link.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task RemoveConnect(string userId);
|
||||
|
||||
/// <summary>
|
||||
/// Invites the user.
|
||||
/// </summary>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <returns>Task<UserLinkResult>.</returns>
|
||||
Task<UserLinkResult> InviteUser(ConnectAuthorizationRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pending guests.
|
||||
/// </summary>
|
||||
/// <returns>Task<List<ConnectAuthorization>>.</returns>
|
||||
Task<List<ConnectAuthorization>> GetPendingGuests();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user from exchange token.
|
||||
/// </summary>
|
||||
/// <param name="token">The token.</param>
|
||||
/// <returns>User.</returns>
|
||||
User GetUserFromExchangeToken(string token);
|
||||
|
||||
/// <summary>
|
||||
/// Cancels the authorization.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task CancelAuthorization(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Authenticates the specified username.
|
||||
/// </summary>
|
||||
Task<ConnectAuthenticationResult> Authenticate(string username, string password, string passwordMd5);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the local user.
|
||||
/// </summary>
|
||||
/// <param name="connectUserId">The connect user identifier.</param>
|
||||
/// <returns>Task<User>.</returns>
|
||||
Task<User> GetLocalUser(string connectUserId);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [is authorization token valid] [the specified token].
|
||||
/// </summary>
|
||||
/// <param name="token">The token.</param>
|
||||
/// <returns><c>true</c> if [is authorization token valid] [the specified token]; otherwise, <c>false</c>.</returns>
|
||||
bool IsAuthorizationTokenValid(string token);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Connect
|
||||
{
|
||||
public class UserLinkResult
|
||||
{
|
||||
public bool IsPending { get; set; }
|
||||
public bool IsNewUserInvitation { get; set; }
|
||||
public string GuestDisplayName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using MediaBrowser.Model.Devices;
|
||||
|
||||
namespace MediaBrowser.Controller.Devices
|
||||
{
|
||||
public class CameraImageUploadInfo
|
||||
{
|
||||
public LocalFileInfo FileInfo { get; set; }
|
||||
public DeviceInfo Device { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
using MediaBrowser.Model.Devices;
|
||||
using MediaBrowser.Model.Events;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Session;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Devices
|
||||
{
|
||||
public interface IDeviceManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs when [device options updated].
|
||||
/// </summary>
|
||||
event EventHandler<GenericEventArgs<DeviceInfo>> DeviceOptionsUpdated;
|
||||
/// <summary>
|
||||
/// Occurs when [camera image uploaded].
|
||||
/// </summary>
|
||||
event EventHandler<GenericEventArgs<CameraImageUploadInfo>> CameraImageUploaded;
|
||||
|
||||
/// <summary>
|
||||
/// Registers the device.
|
||||
/// </summary>
|
||||
/// <param name="reportedId">The reported identifier.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="appName">Name of the application.</param>
|
||||
/// <param name="appVersion">The application version.</param>
|
||||
/// <param name="usedByUserId">The used by user identifier.</param>
|
||||
/// <returns>Task.</returns>
|
||||
DeviceInfo RegisterDevice(string reportedId, string name, string appName, string appVersion, string usedByUserId);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the capabilities.
|
||||
/// </summary>
|
||||
/// <param name="reportedId">The reported identifier.</param>
|
||||
/// <param name="capabilities">The capabilities.</param>
|
||||
/// <returns>Task.</returns>
|
||||
void SaveCapabilities(string reportedId, ClientCapabilities capabilities);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the capabilities.
|
||||
/// </summary>
|
||||
/// <param name="reportedId">The reported identifier.</param>
|
||||
/// <returns>ClientCapabilities.</returns>
|
||||
ClientCapabilities GetCapabilities(string reportedId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the device information.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>DeviceInfo.</returns>
|
||||
DeviceInfo GetDevice(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the device information.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <returns>Task.</returns>
|
||||
void UpdateDeviceInfo(string id, DeviceOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the devices.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>IEnumerable<DeviceInfo>.</returns>
|
||||
QueryResult<DeviceInfo> GetDevices(DeviceQuery query);
|
||||
|
||||
void DeleteDevice(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the upload history.
|
||||
/// </summary>
|
||||
/// <param name="deviceId">The device identifier.</param>
|
||||
/// <returns>ContentUploadHistory.</returns>
|
||||
ContentUploadHistory GetCameraUploadHistory(string deviceId);
|
||||
|
||||
/// <summary>
|
||||
/// Accepts the upload.
|
||||
/// </summary>
|
||||
/// <param name="deviceId">The device identifier.</param>
|
||||
/// <param name="stream">The stream.</param>
|
||||
/// <param name="file">The file.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task AcceptCameraUpload(string deviceId, Stream stream, LocalFileInfo file);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this instance [can access device] the specified user identifier.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <param name="deviceId">The device identifier.</param>
|
||||
/// <returns><c>true</c> if this instance [can access device] the specified user identifier; otherwise, <c>false</c>.</returns>
|
||||
bool CanAccessDevice(string userId, string deviceId);
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using MediaBrowser.Model.Devices;
|
||||
using MediaBrowser.Model.Session;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Devices
|
||||
{
|
||||
public interface IDeviceRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers the device.
|
||||
/// </summary>
|
||||
/// <param name="device">The device.</param>
|
||||
/// <returns>Task.</returns>
|
||||
void SaveDevice(DeviceInfo device);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the capabilities.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <param name="capabilities">The capabilities.</param>
|
||||
/// <returns>Task.</returns>
|
||||
void SaveCapabilities(string id, ClientCapabilities capabilities);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the capabilities.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>ClientCapabilities.</returns>
|
||||
ClientCapabilities GetCapabilities(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the device information.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>DeviceInfo.</returns>
|
||||
DeviceInfo GetDevice(string id);
|
||||
|
||||
List<DeviceInfo> GetDevices();
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the device.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>Task.</returns>
|
||||
void DeleteDevice(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the upload history.
|
||||
/// </summary>
|
||||
/// <param name="deviceId">The device identifier.</param>
|
||||
/// <returns>ContentUploadHistory.</returns>
|
||||
ContentUploadHistory GetCameraUploadHistory(string deviceId);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the camera upload history.
|
||||
/// </summary>
|
||||
/// <param name="deviceId">The device identifier.</param>
|
||||
/// <param name="file">The file.</param>
|
||||
void AddCameraUpload(string deviceId, LocalFileInfo file);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace MediaBrowser.Controller.Dlna
|
||||
{
|
||||
public class ControlRequest
|
||||
{
|
||||
public IDictionary<string, string> Headers { get; set; }
|
||||
|
||||
public Stream InputXml { get; set; }
|
||||
|
||||
public string TargetServerUuId { get; set; }
|
||||
|
||||
public string RequestedUrl { get; set; }
|
||||
|
||||
public ControlRequest()
|
||||
{
|
||||
Headers = new Dictionary<string, string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Dlna
|
||||
{
|
||||
public class ControlResponse
|
||||
{
|
||||
public IDictionary<string, string> Headers { get; set; }
|
||||
|
||||
public string Xml { get; set; }
|
||||
|
||||
public bool IsSuccessful { get; set; }
|
||||
|
||||
public ControlResponse()
|
||||
{
|
||||
Headers = new Dictionary<string, string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Dlna
|
||||
{
|
||||
public class EventSubscriptionResponse
|
||||
{
|
||||
public string Content { get; set; }
|
||||
public string ContentType { get; set; }
|
||||
|
||||
public Dictionary<string, string> Headers { get; set; }
|
||||
|
||||
public EventSubscriptionResponse()
|
||||
{
|
||||
Headers = new Dictionary<string, string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Dlna
|
||||
{
|
||||
public interface IConnectionManager : IEventManager, IUpnpService
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Dlna
|
||||
{
|
||||
public interface IContentDirectory : IEventManager, IUpnpService
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Dlna
|
||||
{
|
||||
public interface IDlnaManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the profile infos.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{DeviceProfileInfo}.</returns>
|
||||
IEnumerable<DeviceProfileInfo> GetProfileInfos();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the profile.
|
||||
/// </summary>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <returns>DeviceProfile.</returns>
|
||||
DeviceProfile GetProfile(IDictionary<string,string> headers);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default profile.
|
||||
/// </summary>
|
||||
/// <returns>DeviceProfile.</returns>
|
||||
DeviceProfile GetDefaultProfile();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the profile.
|
||||
/// </summary>
|
||||
/// <param name="profile">The profile.</param>
|
||||
void CreateProfile(DeviceProfile profile);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the profile.
|
||||
/// </summary>
|
||||
/// <param name="profile">The profile.</param>
|
||||
void UpdateProfile(DeviceProfile profile);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the profile.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
void DeleteProfile(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the profile.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>DeviceProfile.</returns>
|
||||
DeviceProfile GetProfile(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the profile.
|
||||
/// </summary>
|
||||
/// <param name="deviceInfo">The device information.</param>
|
||||
/// <returns>DeviceProfile.</returns>
|
||||
DeviceProfile GetProfile(DeviceIdentification deviceInfo);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the server description XML.
|
||||
/// </summary>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <param name="serverUuId">The server uu identifier.</param>
|
||||
/// <param name="serverAddress">The server address.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
string GetServerDescriptionXml(IDictionary<string, string> headers, string serverUuId, string serverAddress);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the icon.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <returns>DlnaIconResponse.</returns>
|
||||
ImageStream GetIcon(string filename);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Dlna
|
||||
{
|
||||
public interface IEventManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Cancels the event subscription.
|
||||
/// </summary>
|
||||
/// <param name="subscriptionId">The subscription identifier.</param>
|
||||
EventSubscriptionResponse CancelEventSubscription(string subscriptionId);
|
||||
|
||||
/// <summary>
|
||||
/// Renews the event subscription.
|
||||
/// </summary>
|
||||
EventSubscriptionResponse RenewEventSubscription(string subscriptionId, string notificationType, string requestedTimeoutString, string callbackUrl);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the event subscription.
|
||||
/// </summary>
|
||||
EventSubscriptionResponse CreateEventSubscription(string notificationType, string requestedTimeoutString, string callbackUrl);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Dlna
|
||||
{
|
||||
public interface IMediaReceiverRegistrar : IEventManager, IUpnpService
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Dlna
|
||||
{
|
||||
public interface IUpnpService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the content directory XML.
|
||||
/// </summary>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
string GetServiceXml(IDictionary<string, string> headers);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the control request.
|
||||
/// </summary>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <returns>ControlResponse.</returns>
|
||||
ControlResponse ProcessControlRequest(ControlRequest request);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
using System;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
|
||||
namespace MediaBrowser.Controller.Drawing
|
||||
{
|
||||
public interface IImageEncoder
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the supported input formats.
|
||||
/// </summary>
|
||||
/// <value>The supported input formats.</value>
|
||||
string[] SupportedInputFormats { get; }
|
||||
/// <summary>
|
||||
/// Gets the supported output formats.
|
||||
/// </summary>
|
||||
/// <value>The supported output formats.</value>
|
||||
ImageFormat[] SupportedOutputFormats { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Encodes the image.
|
||||
/// </summary>
|
||||
string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat outputFormat);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the image collage.
|
||||
/// </summary>
|
||||
/// <param name="options">The options.</param>
|
||||
void CreateImageCollage(ImageCollageOptions options);
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether [supports image collage creation].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [supports image collage creation]; otherwise, <c>false</c>.</value>
|
||||
bool SupportsImageCollageCreation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether [supports image encoding].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [supports image encoding]; otherwise, <c>false</c>.</value>
|
||||
bool SupportsImageEncoding { get; }
|
||||
|
||||
ImageSize GetImageSize(string path);
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
using System;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Drawing
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IImageProcessor
|
||||
/// </summary>
|
||||
public interface IImageProcessor
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the supported input formats.
|
||||
/// </summary>
|
||||
/// <value>The supported input formats.</value>
|
||||
string[] SupportedInputFormats { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image enhancers.
|
||||
/// </summary>
|
||||
/// <value>The image enhancers.</value>
|
||||
IImageEnhancer[] ImageEnhancers { get; }
|
||||
|
||||
ImageSize GetImageSize(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the image.
|
||||
/// </summary>
|
||||
/// <param name="info">The information.</param>
|
||||
/// <returns>ImageSize.</returns>
|
||||
ImageSize GetImageSize(BaseItem item, ItemImageInfo info);
|
||||
|
||||
ImageSize GetImageSize(BaseItem item, ItemImageInfo info, bool allowSlowMethods, bool updateItem);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the parts.
|
||||
/// </summary>
|
||||
/// <param name="enhancers">The enhancers.</param>
|
||||
void AddParts(IEnumerable<IImageEnhancer> enhancers);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the supported enhancers.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <returns>IEnumerable{IImageEnhancer}.</returns>
|
||||
List<IImageEnhancer> GetSupportedEnhancers(IHasMetadata item, ImageType imageType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image cache tag.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="image">The image.</param>
|
||||
/// <returns>Guid.</returns>
|
||||
string GetImageCacheTag(IHasMetadata item, ItemImageInfo image);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image cache tag.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="image">The image.</param>
|
||||
/// <param name="imageEnhancers">The image enhancers.</param>
|
||||
/// <returns>Guid.</returns>
|
||||
string GetImageCacheTag(IHasMetadata item, ItemImageInfo image, List<IImageEnhancer> imageEnhancers);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the image.
|
||||
/// </summary>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <param name="toStream">To stream.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task ProcessImage(ImageProcessingOptions options, Stream toStream);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the image.
|
||||
/// </summary>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task<Tuple<string, string, DateTime>> ProcessImage(ImageProcessingOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the enhanced image.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <param name="imageIndex">Index of the image.</param>
|
||||
/// <returns>Task{System.String}.</returns>
|
||||
Task<string> GetEnhancedImage(IHasMetadata item, ImageType imageType, int imageIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the supported image output formats.
|
||||
/// </summary>
|
||||
/// <returns>ImageOutputFormat[].</returns>
|
||||
ImageFormat[] GetSupportedImageOutputFormats();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the image collage.
|
||||
/// </summary>
|
||||
/// <param name="options">The options.</param>
|
||||
void CreateImageCollage(ImageCollageOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether [supports image collage creation].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [supports image collage creation]; otherwise, <c>false</c>.</value>
|
||||
bool SupportsImageCollageCreation { get; }
|
||||
|
||||
IImageEncoder ImageEncoder { get; set; }
|
||||
|
||||
bool SupportsTransparency(string path);
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Drawing
|
||||
{
|
||||
public class ImageCollageOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the input paths.
|
||||
/// </summary>
|
||||
/// <value>The input paths.</value>
|
||||
public string[] InputPaths { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the output path.
|
||||
/// </summary>
|
||||
/// <value>The output path.</value>
|
||||
public string OutputPath { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the width.
|
||||
/// </summary>
|
||||
/// <value>The width.</value>
|
||||
public int Width { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the height.
|
||||
/// </summary>
|
||||
/// <value>The height.</value>
|
||||
public int Height { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
using System;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Drawing
|
||||
{
|
||||
public static class ImageHelper
|
||||
{
|
||||
public static ImageSize GetNewImageSize(ImageProcessingOptions options, ImageSize? originalImageSize)
|
||||
{
|
||||
if (originalImageSize.HasValue)
|
||||
{
|
||||
// Determine the output size based on incoming parameters
|
||||
var newSize = DrawingUtils.Resize(originalImageSize.Value, options.Width, options.Height, options.MaxWidth, options.MaxHeight);
|
||||
|
||||
return newSize;
|
||||
}
|
||||
return GetSizeEstimate(options);
|
||||
}
|
||||
|
||||
public static IImageProcessor ImageProcessor { get; set; }
|
||||
|
||||
private static ImageSize GetSizeEstimate(ImageProcessingOptions options)
|
||||
{
|
||||
if (options.Width.HasValue && options.Height.HasValue)
|
||||
{
|
||||
return new ImageSize(options.Width.Value, options.Height.Value);
|
||||
}
|
||||
|
||||
var aspect = GetEstimatedAspectRatio(options.Image.Type, options.Item);
|
||||
|
||||
var width = options.Width ?? options.MaxWidth;
|
||||
|
||||
if (width.HasValue)
|
||||
{
|
||||
var heightValue = width.Value / aspect;
|
||||
return new ImageSize(width.Value, heightValue);
|
||||
}
|
||||
|
||||
var height = options.Height ?? options.MaxHeight ?? 200;
|
||||
var widthValue = aspect * height;
|
||||
return new ImageSize(widthValue, height);
|
||||
}
|
||||
|
||||
private static double GetEstimatedAspectRatio(ImageType type, IHasMetadata item)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ImageType.Art:
|
||||
case ImageType.Backdrop:
|
||||
case ImageType.Chapter:
|
||||
case ImageType.Screenshot:
|
||||
case ImageType.Thumb:
|
||||
return 1.78;
|
||||
case ImageType.Banner:
|
||||
return 5.4;
|
||||
case ImageType.Box:
|
||||
case ImageType.BoxRear:
|
||||
case ImageType.Disc:
|
||||
case ImageType.Menu:
|
||||
return 1;
|
||||
case ImageType.Logo:
|
||||
return 2.58;
|
||||
case ImageType.Primary:
|
||||
return item.GetDefaultPrimaryImageAspectRatio() ?? .667;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Controller.Drawing
|
||||
{
|
||||
public class ImageProcessingOptions
|
||||
{
|
||||
public ImageProcessingOptions()
|
||||
{
|
||||
RequiresAutoOrientation = true;
|
||||
}
|
||||
|
||||
public string ItemId { get; set; }
|
||||
public string ItemType { get; set; }
|
||||
public IHasMetadata Item { get; set; }
|
||||
|
||||
public ItemImageInfo Image { get; set; }
|
||||
|
||||
public int ImageIndex { get; set; }
|
||||
|
||||
public bool CropWhiteSpace { get; set; }
|
||||
|
||||
public int? Width { get; set; }
|
||||
|
||||
public int? Height { get; set; }
|
||||
|
||||
public int? MaxWidth { get; set; }
|
||||
|
||||
public int? MaxHeight { get; set; }
|
||||
|
||||
public int Quality { get; set; }
|
||||
|
||||
public List<IImageEnhancer> Enhancers { get; set; }
|
||||
|
||||
public ImageFormat[] SupportedOutputFormats { get; set; }
|
||||
|
||||
public bool AddPlayedIndicator { get; set; }
|
||||
|
||||
public int? UnplayedCount { get; set; }
|
||||
public int? Blur { get; set; }
|
||||
|
||||
public double PercentPlayed { get; set; }
|
||||
|
||||
public string BackgroundColor { get; set; }
|
||||
public string ForegroundLayer { get; set; }
|
||||
public bool RequiresAutoOrientation { get; set; }
|
||||
|
||||
public bool HasDefaultOptions(string originalImagePath)
|
||||
{
|
||||
return HasDefaultOptionsWithoutSize(originalImagePath) &&
|
||||
!Width.HasValue &&
|
||||
!Height.HasValue &&
|
||||
!MaxWidth.HasValue &&
|
||||
!MaxHeight.HasValue;
|
||||
}
|
||||
|
||||
public bool HasDefaultOptions(string originalImagePath, ImageSize size)
|
||||
{
|
||||
if (!HasDefaultOptionsWithoutSize(originalImagePath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Width.HasValue && !size.Width.Equals(Width.Value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Height.HasValue && !size.Height.Equals(Height.Value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (MaxWidth.HasValue && size.Width > MaxWidth.Value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (MaxHeight.HasValue && size.Height > MaxHeight.Value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool HasDefaultOptionsWithoutSize(string originalImagePath)
|
||||
{
|
||||
return (Quality >= 90) &&
|
||||
IsFormatSupported(originalImagePath) &&
|
||||
!AddPlayedIndicator &&
|
||||
PercentPlayed.Equals(0) &&
|
||||
!UnplayedCount.HasValue &&
|
||||
!Blur.HasValue &&
|
||||
!CropWhiteSpace &&
|
||||
string.IsNullOrEmpty(BackgroundColor) &&
|
||||
string.IsNullOrEmpty(ForegroundLayer);
|
||||
}
|
||||
|
||||
private bool IsFormatSupported(string originalImagePath)
|
||||
{
|
||||
var ext = Path.GetExtension(originalImagePath);
|
||||
return SupportedOutputFormats.Any(outputFormat => string.Equals(ext, "." + outputFormat, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Drawing
|
||||
{
|
||||
public static class ImageProcessorExtensions
|
||||
{
|
||||
public static string GetImageCacheTag(this IImageProcessor processor, IHasMetadata item, ImageType imageType)
|
||||
{
|
||||
return processor.GetImageCacheTag(item, imageType, 0);
|
||||
}
|
||||
|
||||
public static string GetImageCacheTag(this IImageProcessor processor, IHasMetadata item, ImageType imageType, int imageIndex)
|
||||
{
|
||||
var imageInfo = item.GetImageInfo(imageType, imageIndex);
|
||||
|
||||
if (imageInfo == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return processor.GetImageCacheTag(item, imageInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace MediaBrowser.Controller.Drawing
|
||||
{
|
||||
public class ImageStream : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the stream.
|
||||
/// </summary>
|
||||
/// <value>The stream.</value>
|
||||
public Stream Stream { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the format.
|
||||
/// </summary>
|
||||
/// <value>The format.</value>
|
||||
public ImageFormat Format { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Stream != null)
|
||||
{
|
||||
Stream.Dispose();
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Controller.Dto
|
||||
{
|
||||
public class DtoOptions
|
||||
{
|
||||
private static readonly List<ItemFields> DefaultExcludedFields = new List<ItemFields>
|
||||
{
|
||||
ItemFields.SeasonUserData,
|
||||
ItemFields.RefreshState
|
||||
};
|
||||
|
||||
public ItemFields[] Fields { get; set; }
|
||||
public ImageType[] ImageTypes { get; set; }
|
||||
public int ImageTypeLimit { get; set; }
|
||||
public bool EnableImages { get; set; }
|
||||
public bool AddProgramRecordingInfo { get; set; }
|
||||
public string DeviceId { get; set; }
|
||||
public bool EnableUserData { get; set; }
|
||||
public bool AddCurrentProgram { get; set; }
|
||||
|
||||
public DtoOptions()
|
||||
: this(true)
|
||||
{
|
||||
}
|
||||
|
||||
private static readonly ImageType[] AllImageTypes = Enum.GetNames(typeof(ImageType))
|
||||
.Select(i => (ImageType)Enum.Parse(typeof(ImageType), i, true))
|
||||
.ToArray();
|
||||
|
||||
private static readonly ItemFields[] AllItemFields = Enum.GetNames(typeof(ItemFields))
|
||||
.Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
|
||||
.Except(DefaultExcludedFields)
|
||||
.ToArray();
|
||||
|
||||
public DtoOptions(bool allFields)
|
||||
{
|
||||
ImageTypeLimit = int.MaxValue;
|
||||
EnableImages = true;
|
||||
EnableUserData = true;
|
||||
AddCurrentProgram = true;
|
||||
|
||||
if (allFields)
|
||||
{
|
||||
Fields = AllItemFields;
|
||||
}
|
||||
else
|
||||
{
|
||||
Fields = new ItemFields[] { };
|
||||
}
|
||||
|
||||
ImageTypes = AllImageTypes;
|
||||
}
|
||||
|
||||
public int GetImageLimit(ImageType type)
|
||||
{
|
||||
if (EnableImages && ImageTypes.Contains(type))
|
||||
{
|
||||
return ImageTypeLimit;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Controller.Sync;
|
||||
|
||||
namespace MediaBrowser.Controller.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IDtoService
|
||||
/// </summary>
|
||||
public interface IDtoService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the dto id.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
string GetDtoId(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the primary image aspect ratio.
|
||||
/// </summary>
|
||||
/// <param name="dto">The dto.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
void AttachPrimaryImageAspectRatio(IItemDto dto, BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the primary image aspect ratio.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>System.Nullable<System.Double>.</returns>
|
||||
double? GetPrimaryImageAspectRatio(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base item dto.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="fields">The fields.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="owner">The owner.</param>
|
||||
BaseItemDto GetBaseItemDto(BaseItem item, ItemFields[] fields, User user = null, BaseItem owner = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base item dto.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="owner">The owner.</param>
|
||||
/// <returns>BaseItemDto.</returns>
|
||||
BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base item dtos.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="owner">The owner.</param>
|
||||
BaseItemDto[] GetBaseItemDtos(BaseItem[] items, DtoOptions options, User user = null, BaseItem owner = null);
|
||||
|
||||
BaseItemDto[] GetBaseItemDtos(List<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the chapter information dto.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>ChapterInfoDto.</returns>
|
||||
List<ChapterInfoDto> GetChapterInfoDtos(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user item data dto.
|
||||
/// </summary>
|
||||
/// <param name="data">The data.</param>
|
||||
/// <returns>UserItemDataDto.</returns>
|
||||
UserItemDataDto GetUserItemDataDto(UserItemData data);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item by name dto.
|
||||
/// </summary>
|
||||
BaseItemDto GetItemByNameDto(BaseItem item, DtoOptions options, List<BaseItem> taggedItems, Dictionary<string, SyncedItemProgress> syncProgress, User user = null);
|
||||
|
||||
Dictionary<string, SyncedItemProgress> GetSyncedItemProgress(DtoOptions options);
|
||||
}
|
||||
}
|
||||
@@ -1,225 +0,0 @@
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Specialized folder that can have items added to it's children by external entities.
|
||||
/// Used for our RootFolder so plug-ins can add items.
|
||||
/// </summary>
|
||||
public class AggregateFolder : Folder
|
||||
{
|
||||
public AggregateFolder()
|
||||
{
|
||||
PhysicalLocationsList = EmptyStringArray;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool IsPhysicalRoot
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPlayedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The _virtual children
|
||||
/// </summary>
|
||||
private readonly ConcurrentBag<BaseItem> _virtualChildren = new ConcurrentBag<BaseItem>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the virtual children.
|
||||
/// </summary>
|
||||
/// <value>The virtual children.</value>
|
||||
public ConcurrentBag<BaseItem> VirtualChildren
|
||||
{
|
||||
get { return _virtualChildren; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override string[] PhysicalLocations
|
||||
{
|
||||
get
|
||||
{
|
||||
return PhysicalLocationsList;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] PhysicalLocationsList { get; set; }
|
||||
|
||||
protected override FileSystemMetadata[] GetFileSystemChildren(IDirectoryService directoryService)
|
||||
{
|
||||
return CreateResolveArgs(directoryService, true).FileSystemChildren;
|
||||
}
|
||||
|
||||
private Guid[] _childrenIds = null;
|
||||
private readonly object _childIdsLock = new object();
|
||||
protected override List<BaseItem> LoadChildren()
|
||||
{
|
||||
lock (_childIdsLock)
|
||||
{
|
||||
if (_childrenIds == null || _childrenIds.Length == 0)
|
||||
{
|
||||
var list = base.LoadChildren();
|
||||
_childrenIds = list.Select(i => i.Id).ToArray();
|
||||
return list;
|
||||
}
|
||||
|
||||
return _childrenIds.Select(LibraryManager.GetItemById).Where(i => i != null).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearCache()
|
||||
{
|
||||
lock (_childIdsLock)
|
||||
{
|
||||
_childrenIds = null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _requiresRefresh;
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var changed = base.RequiresRefresh() || _requiresRefresh;
|
||||
|
||||
if (!changed)
|
||||
{
|
||||
var locations = PhysicalLocations;
|
||||
|
||||
var newLocations = CreateResolveArgs(new DirectoryService(Logger, FileSystem), false).PhysicalLocations;
|
||||
|
||||
if (!locations.SequenceEqual(newLocations))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
ClearCache();
|
||||
|
||||
var changed = base.BeforeMetadataRefresh() || _requiresRefresh;
|
||||
_requiresRefresh = false;
|
||||
return changed;
|
||||
}
|
||||
|
||||
private ItemResolveArgs CreateResolveArgs(IDirectoryService directoryService, bool setPhysicalLocations)
|
||||
{
|
||||
ClearCache();
|
||||
|
||||
var path = ContainingFolderPath;
|
||||
|
||||
var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService)
|
||||
{
|
||||
FileInfo = FileSystem.GetDirectoryInfo(path),
|
||||
Path = path,
|
||||
Parent = GetParent() as Folder
|
||||
};
|
||||
|
||||
// Gather child folder and files
|
||||
if (args.IsDirectory)
|
||||
{
|
||||
var isPhysicalRoot = args.IsPhysicalRoot;
|
||||
|
||||
// When resolving the root, we need it's grandchildren (children of user views)
|
||||
var flattenFolderDepth = isPhysicalRoot ? 2 : 0;
|
||||
|
||||
var files = FileData.GetFilteredFileSystemEntries(directoryService, args.Path, FileSystem, Logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf);
|
||||
|
||||
// Need to remove subpaths that may have been resolved from shortcuts
|
||||
// Example: if \\server\movies exists, then strip out \\server\movies\action
|
||||
if (isPhysicalRoot)
|
||||
{
|
||||
files = LibraryManager.NormalizeRootPathList(files).ToArray();
|
||||
}
|
||||
|
||||
args.FileSystemChildren = files;
|
||||
}
|
||||
|
||||
_requiresRefresh = _requiresRefresh || !args.PhysicalLocations.SequenceEqual(PhysicalLocations);
|
||||
if (setPhysicalLocations)
|
||||
{
|
||||
PhysicalLocationsList = args.PhysicalLocations;
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
|
||||
{
|
||||
return base.GetNonCachedChildren(directoryService).Concat(_virtualChildren);
|
||||
}
|
||||
|
||||
protected override async Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
|
||||
{
|
||||
ClearCache();
|
||||
|
||||
await base.ValidateChildrenInternal(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
ClearCache();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the virtual child.
|
||||
/// </summary>
|
||||
/// <param name="child">The child.</param>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
public void AddVirtualChild(BaseItem child)
|
||||
{
|
||||
if (child == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
_virtualChildren.Add(child);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the virtual child.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">id</exception>
|
||||
public BaseItem FindVirtualChild(Guid id)
|
||||
{
|
||||
if (id == Guid.Empty)
|
||||
{
|
||||
throw new ArgumentNullException("id");
|
||||
}
|
||||
|
||||
foreach (var child in _virtualChildren)
|
||||
{
|
||||
if (child.Id == id)
|
||||
{
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,296 +0,0 @@
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Audio
|
||||
/// </summary>
|
||||
public class Audio : BaseItem,
|
||||
IHasAlbumArtist,
|
||||
IHasArtist,
|
||||
IHasMusicGenres,
|
||||
IHasLookupInfo<SongInfo>,
|
||||
IHasMediaSources
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the artist.
|
||||
/// </summary>
|
||||
/// <value>The artist.</value>
|
||||
[IgnoreDataMember]
|
||||
public string[] Artists { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string[] AlbumArtists { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool EnableRefreshOnDateModifiedChange
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public Audio()
|
||||
{
|
||||
Artists = EmptyStringArray;
|
||||
AlbumArtists = EmptyStringArray;
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPlayedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsAddingToPlaylist
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsInheritedParentImages
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
protected override bool SupportsOwnedItems
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override Folder LatestItemsIndexContainer
|
||||
{
|
||||
get
|
||||
{
|
||||
return AlbumEntity;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanDownload()
|
||||
{
|
||||
var locationType = LocationType;
|
||||
return locationType != LocationType.Remote &&
|
||||
locationType != LocationType.Virtual;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string[] AllArtists
|
||||
{
|
||||
get
|
||||
{
|
||||
var list = new string[AlbumArtists.Length + Artists.Length];
|
||||
|
||||
var index = 0;
|
||||
foreach (var artist in AlbumArtists)
|
||||
{
|
||||
list[index] = artist;
|
||||
index++;
|
||||
}
|
||||
foreach (var artist in Artists)
|
||||
{
|
||||
list[index] = artist;
|
||||
index++;
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public MusicAlbum AlbumEntity
|
||||
{
|
||||
get { return FindParent<MusicAlbum>(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the media.
|
||||
/// </summary>
|
||||
/// <value>The type of the media.</value>
|
||||
[IgnoreDataMember]
|
||||
public override string MediaType
|
||||
{
|
||||
get
|
||||
{
|
||||
return Model.Entities.MediaType.Audio;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the name of the sort.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateSortName()
|
||||
{
|
||||
return (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("0000 - ") : "")
|
||||
+ (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name;
|
||||
}
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
var songKey = IndexNumber.HasValue ? IndexNumber.Value.ToString("0000") : string.Empty;
|
||||
|
||||
|
||||
if (ParentIndexNumber.HasValue)
|
||||
{
|
||||
songKey = ParentIndexNumber.Value.ToString("0000") + "-" + songKey;
|
||||
}
|
||||
songKey += Name;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Album))
|
||||
{
|
||||
songKey = Album + "-" + songKey;
|
||||
}
|
||||
|
||||
var albumArtist = AlbumArtists.Length == 0 ? null : AlbumArtists[0];
|
||||
if (!string.IsNullOrWhiteSpace(albumArtist))
|
||||
{
|
||||
songKey = albumArtist + "-" + songKey;
|
||||
}
|
||||
|
||||
list.Insert(0, songKey);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
if (SourceType == SourceType.Library)
|
||||
{
|
||||
return UnratedItem.Music;
|
||||
}
|
||||
return base.GetBlockUnratedType();
|
||||
}
|
||||
|
||||
public List<MediaStream> GetMediaStreams()
|
||||
{
|
||||
return MediaSourceManager.GetMediaStreams(new MediaStreamQuery
|
||||
{
|
||||
ItemId = Id
|
||||
});
|
||||
}
|
||||
|
||||
public List<MediaStream> GetMediaStreams(MediaStreamType type)
|
||||
{
|
||||
return MediaSourceManager.GetMediaStreams(new MediaStreamQuery
|
||||
{
|
||||
ItemId = Id,
|
||||
Type = type
|
||||
});
|
||||
}
|
||||
|
||||
public SongInfo GetLookupInfo()
|
||||
{
|
||||
var info = GetItemLookupInfo<SongInfo>();
|
||||
|
||||
info.AlbumArtists = AlbumArtists;
|
||||
info.Album = Album;
|
||||
info.Artists = Artists;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public virtual List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
{
|
||||
if (SourceType == SourceType.Channel)
|
||||
{
|
||||
var sources = ChannelManager.GetStaticMediaSources(this, CancellationToken.None)
|
||||
.ToList();
|
||||
|
||||
if (sources.Count > 0)
|
||||
{
|
||||
return sources;
|
||||
}
|
||||
|
||||
var list = new List<MediaSourceInfo>
|
||||
{
|
||||
GetVersionInfo(this, enablePathSubstitution)
|
||||
};
|
||||
|
||||
foreach (var mediaSource in list)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(mediaSource.Path))
|
||||
{
|
||||
mediaSource.Type = MediaSourceType.Placeholder;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
var result = new List<MediaSourceInfo>
|
||||
{
|
||||
GetVersionInfo(this, enablePathSubstitution)
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static MediaSourceInfo GetVersionInfo(Audio i, bool enablePathSubstituion)
|
||||
{
|
||||
var locationType = i.LocationType;
|
||||
|
||||
var info = new MediaSourceInfo
|
||||
{
|
||||
Id = i.Id.ToString("N"),
|
||||
Protocol = locationType == LocationType.Remote ? MediaProtocol.Http : MediaProtocol.File,
|
||||
MediaStreams = MediaSourceManager.GetMediaStreams(i.Id),
|
||||
Name = i.Name,
|
||||
Path = enablePathSubstituion ? GetMappedPath(i, i.Path, locationType) : i.Path,
|
||||
RunTimeTicks = i.RunTimeTicks,
|
||||
Container = i.Container,
|
||||
Size = i.Size
|
||||
};
|
||||
|
||||
if (info.Protocol == MediaProtocol.File)
|
||||
{
|
||||
info.ETag = i.DateModified.Ticks.ToString(CultureInfo.InvariantCulture).GetMD5().ToString("N");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(info.Container))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(i.Path) && locationType != LocationType.Remote && locationType != LocationType.Virtual)
|
||||
{
|
||||
info.Container = System.IO.Path.GetExtension(i.Path).TrimStart('.');
|
||||
}
|
||||
}
|
||||
|
||||
info.Bitrate = i.TotalBitrate;
|
||||
info.InferTotalBitrate();
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
public class AudioPodcast : Audio, IHasLookupInfo<SongInfo>
|
||||
{
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPositionTicksResume
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPlayedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
public interface IHasAlbumArtist
|
||||
{
|
||||
string[] AlbumArtists { get; set; }
|
||||
}
|
||||
|
||||
public interface IHasArtist
|
||||
{
|
||||
string[] AllArtists { get; }
|
||||
|
||||
string[] Artists { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
public interface IHasMusicGenres
|
||||
{
|
||||
List<string> Genres { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,272 +0,0 @@
|
||||
using System;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Users;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Class MusicAlbum
|
||||
/// </summary>
|
||||
public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo<AlbumInfo>, IMetadataContainer
|
||||
{
|
||||
public string[] AlbumArtists { get; set; }
|
||||
public string[] Artists { get; set; }
|
||||
|
||||
public MusicAlbum()
|
||||
{
|
||||
Artists = EmptyStringArray;
|
||||
AlbumArtists = EmptyStringArray;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsAddingToPlaylist
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsInheritedParentImages
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public MusicArtist MusicArtist
|
||||
{
|
||||
get { return GetMusicArtist(new DtoOptions(true)); }
|
||||
}
|
||||
|
||||
public MusicArtist GetMusicArtist(DtoOptions options)
|
||||
{
|
||||
var parents = GetParents();
|
||||
foreach (var parent in parents)
|
||||
{
|
||||
var artist = parent as MusicArtist;
|
||||
if (artist != null)
|
||||
{
|
||||
return artist;
|
||||
}
|
||||
}
|
||||
|
||||
var name = AlbumArtist;
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return LibraryManager.GetArtist(name, options);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPlayedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsCumulativeRunTimeTicks
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string[] AllArtists
|
||||
{
|
||||
get
|
||||
{
|
||||
var list = new string[AlbumArtists.Length + Artists.Length];
|
||||
|
||||
var index = 0;
|
||||
foreach (var artist in AlbumArtists)
|
||||
{
|
||||
list[index] = artist;
|
||||
index++;
|
||||
}
|
||||
foreach (var artist in Artists)
|
||||
{
|
||||
list[index] = artist;
|
||||
index++;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string AlbumArtist
|
||||
{
|
||||
get { return AlbumArtists.Length == 0 ? null : AlbumArtists[0]; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tracks.
|
||||
/// </summary>
|
||||
/// <value>The tracks.</value>
|
||||
[IgnoreDataMember]
|
||||
public IEnumerable<BaseItem> Tracks
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetRecursiveChildren(i => i is Audio);
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
|
||||
{
|
||||
return Tracks;
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
var albumArtist = AlbumArtist;
|
||||
if (!string.IsNullOrWhiteSpace(albumArtist))
|
||||
{
|
||||
list.Insert(0, albumArtist + "-" + Name);
|
||||
}
|
||||
|
||||
var id = this.GetProviderId(MetadataProviders.MusicBrainzAlbum);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(id))
|
||||
{
|
||||
list.Insert(0, "MusicAlbum-Musicbrainz-" + id);
|
||||
}
|
||||
|
||||
id = this.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(id))
|
||||
{
|
||||
list.Insert(0, "MusicAlbum-MusicBrainzReleaseGroup-" + id);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
{
|
||||
return config.BlockUnratedItems.Contains(UnratedItem.Music);
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Music;
|
||||
}
|
||||
|
||||
public AlbumInfo GetLookupInfo()
|
||||
{
|
||||
var id = GetItemLookupInfo<AlbumInfo>();
|
||||
|
||||
id.AlbumArtists = AlbumArtists;
|
||||
|
||||
var artist = GetMusicArtist(new DtoOptions(false));
|
||||
|
||||
if (artist != null)
|
||||
{
|
||||
id.ArtistProviderIds = artist.ProviderIds;
|
||||
}
|
||||
|
||||
id.SongInfos = GetRecursiveChildren(i => i is Audio)
|
||||
.Cast<Audio>()
|
||||
.Select(i => i.GetLookupInfo())
|
||||
.ToList();
|
||||
|
||||
var album = id.SongInfos
|
||||
.Select(i => i.Album)
|
||||
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(album))
|
||||
{
|
||||
id.Name = album;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
var items = GetRecursiveChildren();
|
||||
|
||||
var totalItems = items.Count;
|
||||
var numComplete = 0;
|
||||
|
||||
var childUpdateType = ItemUpdateType.None;
|
||||
|
||||
// Refresh songs
|
||||
foreach (var item in items)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var updateType = await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
childUpdateType = childUpdateType | updateType;
|
||||
|
||||
numComplete++;
|
||||
double percent = numComplete;
|
||||
percent /= totalItems;
|
||||
progress.Report(percent * 95);
|
||||
}
|
||||
|
||||
var parentRefreshOptions = refreshOptions;
|
||||
if (childUpdateType > ItemUpdateType.None)
|
||||
{
|
||||
parentRefreshOptions = new MetadataRefreshOptions(refreshOptions);
|
||||
parentRefreshOptions.MetadataRefreshMode = MetadataRefreshMode.FullRefresh;
|
||||
}
|
||||
|
||||
// Refresh current item
|
||||
await RefreshMetadata(parentRefreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!refreshOptions.IsAutomated)
|
||||
{
|
||||
await RefreshArtists(refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshArtists(MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
var all = AllArtists;
|
||||
foreach (var i in all)
|
||||
{
|
||||
// This should not be necessary but we're seeing some cases of it
|
||||
if (string.IsNullOrWhiteSpace(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var artist = LibraryManager.GetArtist(i);
|
||||
|
||||
if (!artist.IsAccessedByName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
await artist.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,345 +0,0 @@
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Class MusicArtist
|
||||
/// </summary>
|
||||
public class MusicArtist : Folder, IMetadataContainer, IItemByName, IHasMusicGenres, IHasDualAccess, IHasLookupInfo<ArtistInfo>
|
||||
{
|
||||
[IgnoreDataMember]
|
||||
public bool IsAccessedByName
|
||||
{
|
||||
get { return ParentId == Guid.Empty; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool IsFolder
|
||||
{
|
||||
get
|
||||
{
|
||||
return !IsAccessedByName;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsInheritedParentImages
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsCumulativeRunTimeTicks
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool IsDisplayedAsFolder
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsAddingToPlaylist
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPlayedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return !IsAccessedByName;
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
{
|
||||
if (query.IncludeItemTypes.Length == 0)
|
||||
{
|
||||
query.IncludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicVideo).Name, typeof(MusicAlbum).Name };
|
||||
query.ArtistIds = new[] { Id.ToString("N") };
|
||||
}
|
||||
|
||||
return LibraryManager.GetItemList(query);
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override IEnumerable<BaseItem> Children
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
return new List<BaseItem>();
|
||||
}
|
||||
|
||||
return base.Children;
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetChildCount(User user)
|
||||
{
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return base.GetChildCount(user);
|
||||
}
|
||||
|
||||
public override bool IsSaveLocalMetadataEnabled()
|
||||
{
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.IsSaveLocalMetadataEnabled();
|
||||
}
|
||||
|
||||
private readonly Task _cachedTask = Task.FromResult(true);
|
||||
protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
|
||||
{
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
// Should never get in here anyway
|
||||
return _cachedTask;
|
||||
}
|
||||
|
||||
return base.ValidateChildrenInternal(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService);
|
||||
}
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.InsertRange(0, GetUserDataKeys(this));
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the folder containing the item.
|
||||
/// If the item is a folder, it returns the folder itself
|
||||
/// </summary>
|
||||
/// <value>The containing folder path.</value>
|
||||
[IgnoreDataMember]
|
||||
public override string ContainingFolderPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is owned item.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
|
||||
[IgnoreDataMember]
|
||||
public override bool IsOwnedItem
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data key.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private static List<string> GetUserDataKeys(MusicArtist item)
|
||||
{
|
||||
var list = new List<string>();
|
||||
var id = item.GetProviderId(MetadataProviders.MusicBrainzArtist);
|
||||
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
list.Add("Artist-Musicbrainz-" + id);
|
||||
}
|
||||
|
||||
list.Add("Artist-" + (item.Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return "Artist-" + (Name ?? string.Empty).RemoveDiacritics();
|
||||
}
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
{
|
||||
return config.BlockUnratedItems.Contains(UnratedItem.Music);
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Music;
|
||||
}
|
||||
|
||||
public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
var items = GetRecursiveChildren();
|
||||
|
||||
var totalItems = items.Count;
|
||||
var numComplete = 0;
|
||||
|
||||
var childUpdateType = ItemUpdateType.None;
|
||||
|
||||
// Refresh songs
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (!(item is Audio))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var updateType = await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
childUpdateType = childUpdateType | updateType;
|
||||
|
||||
numComplete++;
|
||||
double percent = numComplete;
|
||||
percent /= totalItems;
|
||||
progress.Report(percent * 100);
|
||||
}
|
||||
|
||||
var parentRefreshOptions = refreshOptions;
|
||||
if (childUpdateType > ItemUpdateType.None)
|
||||
{
|
||||
parentRefreshOptions = new MetadataRefreshOptions(refreshOptions);
|
||||
parentRefreshOptions.MetadataRefreshMode = MetadataRefreshMode.FullRefresh;
|
||||
}
|
||||
|
||||
// Refresh current item
|
||||
await RefreshMetadata(parentRefreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Refresh all non-songs
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item is Audio)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var updateType = await item.RefreshMetadata(parentRefreshOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
numComplete++;
|
||||
double percent = numComplete;
|
||||
percent /= totalItems;
|
||||
progress.Report(percent * 100);
|
||||
}
|
||||
}
|
||||
|
||||
public ArtistInfo GetLookupInfo()
|
||||
{
|
||||
var info = GetItemLookupInfo<ArtistInfo>();
|
||||
|
||||
info.SongInfos = GetRecursiveChildren(i => i is Audio)
|
||||
.Cast<Audio>()
|
||||
.Select(i => i.GetLookupInfo())
|
||||
.ToList();
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPath(string name)
|
||||
{
|
||||
return GetPath(name, true);
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validName = normalizeName ?
|
||||
FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
|
||||
name;
|
||||
|
||||
return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.ArtistsPath, validName);
|
||||
}
|
||||
|
||||
private string GetRebasedPath()
|
||||
{
|
||||
return GetPath(System.IO.Path.GetFileName(Path), false);
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Path = newPath;
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// Class MusicGenre
|
||||
/// </summary>
|
||||
public class MusicGenre : BaseItem, IItemByName
|
||||
{
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return GetUserDataKeys()[0];
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsAddingToPlaylist
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsAncestors
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool IsDisplayedAsFolder
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the folder containing the item.
|
||||
/// If the item is a folder, it returns the folder itself
|
||||
/// </summary>
|
||||
/// <value>The containing folder path.</value>
|
||||
[IgnoreDataMember]
|
||||
public override string ContainingFolderPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path;
|
||||
}
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsSaveLocalMetadataEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is owned item.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
|
||||
[IgnoreDataMember]
|
||||
public override bool IsOwnedItem
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
{
|
||||
query.GenreIds = new[] { Id.ToString("N") };
|
||||
query.IncludeItemTypes = new[] { typeof(MusicVideo).Name, typeof(Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name };
|
||||
|
||||
return LibraryManager.GetItemList(query);
|
||||
}
|
||||
|
||||
public static string GetPath(string name)
|
||||
{
|
||||
return GetPath(name, true);
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validName = normalizeName ?
|
||||
FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
|
||||
name;
|
||||
|
||||
return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.MusicGenrePath, validName);
|
||||
}
|
||||
|
||||
private string GetRebasedPath()
|
||||
{
|
||||
return GetPath(System.IO.Path.GetFileName(Path), false);
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Path = newPath;
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
using System;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class AudioBook : Audio.Audio, IHasSeries, IHasLookupInfo<SongInfo>
|
||||
{
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPositionTicksResume
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPlayedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string SeriesPresentationUniqueKey { get; set; }
|
||||
[IgnoreDataMember]
|
||||
public string SeriesName { get; set; }
|
||||
[IgnoreDataMember]
|
||||
public Guid? SeriesId { get; set; }
|
||||
|
||||
public string FindSeriesSortName()
|
||||
{
|
||||
return SeriesName;
|
||||
}
|
||||
public string FindSeriesName()
|
||||
{
|
||||
return SeriesName;
|
||||
}
|
||||
public string FindSeriesPresentationUniqueKey()
|
||||
{
|
||||
return SeriesPresentationUniqueKey;
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public Guid? FindSeriesId()
|
||||
{
|
||||
return SeriesId;
|
||||
}
|
||||
|
||||
public override bool CanDownload()
|
||||
{
|
||||
var locationType = LocationType;
|
||||
return locationType != LocationType.Remote &&
|
||||
locationType != LocationType.Virtual;
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Book;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,54 +0,0 @@
|
||||
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Plugins derive from and export this class to create a folder that will appear in the root along
|
||||
/// with all the other actual physical folders in the system.
|
||||
/// </summary>
|
||||
public abstract class BasePluginFolder : Folder, ICollectionFolder
|
||||
{
|
||||
[IgnoreDataMember]
|
||||
public virtual string CollectionType
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsSaveLocalMetadataEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsInheritedParentImages
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
//{
|
||||
// double value = 16;
|
||||
// value /= 9;
|
||||
|
||||
// return value;
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class Book : BaseItem, IHasLookupInfo<BookInfo>, IHasSeries
|
||||
{
|
||||
[IgnoreDataMember]
|
||||
public override string MediaType
|
||||
{
|
||||
get
|
||||
{
|
||||
return Model.Entities.MediaType.Book;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string SeriesPresentationUniqueKey { get; set; }
|
||||
[IgnoreDataMember]
|
||||
public string SeriesName { get; set; }
|
||||
[IgnoreDataMember]
|
||||
public Guid? SeriesId { get; set; }
|
||||
|
||||
public string FindSeriesSortName()
|
||||
{
|
||||
return SeriesName;
|
||||
}
|
||||
public string FindSeriesName()
|
||||
{
|
||||
return SeriesName;
|
||||
}
|
||||
public string FindSeriesPresentationUniqueKey()
|
||||
{
|
||||
return SeriesPresentationUniqueKey;
|
||||
}
|
||||
|
||||
public Guid? FindSeriesId()
|
||||
{
|
||||
return SeriesId;
|
||||
}
|
||||
|
||||
public override bool CanDownload()
|
||||
{
|
||||
var locationType = LocationType;
|
||||
return locationType != LocationType.Remote &&
|
||||
locationType != LocationType.Virtual;
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Book;
|
||||
}
|
||||
|
||||
public BookInfo GetLookupInfo()
|
||||
{
|
||||
var info = GetItemLookupInfo<BookInfo>();
|
||||
|
||||
if (string.IsNullOrEmpty(SeriesName))
|
||||
{
|
||||
info.SeriesName = GetParents().Select(i => i.Name).FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
info.SeriesName = SeriesName;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,387 +0,0 @@
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Specialized Folder class that points to a subset of the physical folders in the system.
|
||||
/// It is created from the user-specific folders within the system root
|
||||
/// </summary>
|
||||
public class CollectionFolder : Folder, ICollectionFolder
|
||||
{
|
||||
public static IXmlSerializer XmlSerializer { get; set; }
|
||||
|
||||
public CollectionFolder()
|
||||
{
|
||||
PhysicalLocationsList = EmptyStringArray;
|
||||
PhysicalFolderIds = EmptyGuidArray;
|
||||
}
|
||||
|
||||
//public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
//{
|
||||
// double value = 16;
|
||||
// value /= 9;
|
||||
|
||||
// return value;
|
||||
//}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPlayedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsInheritedParentImages
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public string CollectionType { get; set; }
|
||||
|
||||
private static readonly Dictionary<string, LibraryOptions> LibraryOptions = new Dictionary<string, LibraryOptions>();
|
||||
public LibraryOptions GetLibraryOptions()
|
||||
{
|
||||
return GetLibraryOptions(Path);
|
||||
}
|
||||
|
||||
private static LibraryOptions LoadLibraryOptions(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = XmlSerializer.DeserializeFromFile(typeof(LibraryOptions), GetLibraryOptionsPath(path)) as LibraryOptions;
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
return new LibraryOptions();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
return new LibraryOptions();
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return new LibraryOptions();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.ErrorException("Error loading library options", ex);
|
||||
|
||||
return new LibraryOptions();
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetLibraryOptionsPath(string path)
|
||||
{
|
||||
return System.IO.Path.Combine(path, "options.xml");
|
||||
}
|
||||
|
||||
public void UpdateLibraryOptions(LibraryOptions options)
|
||||
{
|
||||
SaveLibraryOptions(Path, options);
|
||||
}
|
||||
|
||||
public static LibraryOptions GetLibraryOptions(string path)
|
||||
{
|
||||
lock (LibraryOptions)
|
||||
{
|
||||
LibraryOptions options;
|
||||
if (!LibraryOptions.TryGetValue(path, out options))
|
||||
{
|
||||
options = LoadLibraryOptions(path);
|
||||
LibraryOptions[path] = options;
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SaveLibraryOptions(string path, LibraryOptions options)
|
||||
{
|
||||
lock (LibraryOptions)
|
||||
{
|
||||
LibraryOptions[path] = options;
|
||||
|
||||
XmlSerializer.SerializeToFile(options, GetLibraryOptionsPath(path));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allow different display preferences for each collection folder
|
||||
/// </summary>
|
||||
/// <value>The display prefs id.</value>
|
||||
[IgnoreDataMember]
|
||||
public override Guid DisplayPreferencesId
|
||||
{
|
||||
get
|
||||
{
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override string[] PhysicalLocations
|
||||
{
|
||||
get
|
||||
{
|
||||
return PhysicalLocationsList;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsSaveLocalMetadataEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public string[] PhysicalLocationsList { get; set; }
|
||||
public Guid[] PhysicalFolderIds { get; set; }
|
||||
|
||||
protected override FileSystemMetadata[] GetFileSystemChildren(IDirectoryService directoryService)
|
||||
{
|
||||
return CreateResolveArgs(directoryService, true).FileSystemChildren;
|
||||
}
|
||||
|
||||
private bool _requiresRefresh;
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var changed = base.RequiresRefresh() || _requiresRefresh;
|
||||
|
||||
if (!changed)
|
||||
{
|
||||
var locations = PhysicalLocations;
|
||||
|
||||
var newLocations = CreateResolveArgs(new DirectoryService(Logger, FileSystem), false).PhysicalLocations;
|
||||
|
||||
if (!locations.SequenceEqual(newLocations))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!changed)
|
||||
{
|
||||
var folderIds = PhysicalFolderIds;
|
||||
|
||||
var newFolderIds = GetPhysicalFolders(false).Select(i => i.Id).ToList();
|
||||
|
||||
if (!folderIds.SequenceEqual(newFolderIds))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var changed = base.BeforeMetadataRefresh() || _requiresRefresh;
|
||||
_requiresRefresh = false;
|
||||
return changed;
|
||||
}
|
||||
|
||||
public override double? GetRefreshProgress()
|
||||
{
|
||||
var folders = GetPhysicalFolders(true).ToList();
|
||||
double totalProgresses = 0;
|
||||
var foldersWithProgress = 0;
|
||||
|
||||
foreach (var folder in folders)
|
||||
{
|
||||
var progress = ProviderManager.GetRefreshProgress(folder.Id);
|
||||
if (progress.HasValue)
|
||||
{
|
||||
totalProgresses += progress.Value;
|
||||
foldersWithProgress++;
|
||||
}
|
||||
}
|
||||
|
||||
if (foldersWithProgress == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return (totalProgresses / foldersWithProgress);
|
||||
}
|
||||
|
||||
protected override bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren)
|
||||
{
|
||||
return RefreshLinkedChildrenInternal(true);
|
||||
}
|
||||
|
||||
private bool RefreshLinkedChildrenInternal(bool setFolders)
|
||||
{
|
||||
var physicalFolders = GetPhysicalFolders(false)
|
||||
.ToList();
|
||||
|
||||
var linkedChildren = physicalFolders
|
||||
.SelectMany(c => c.LinkedChildren)
|
||||
.ToList();
|
||||
|
||||
var changed = !linkedChildren.SequenceEqual(LinkedChildren, new LinkedChildComparer(FileSystem));
|
||||
|
||||
LinkedChildren = linkedChildren.ToArray(linkedChildren.Count);
|
||||
|
||||
var folderIds = PhysicalFolderIds;
|
||||
var newFolderIds = physicalFolders.Select(i => i.Id).ToArray();
|
||||
|
||||
if (!folderIds.SequenceEqual(newFolderIds))
|
||||
{
|
||||
changed = true;
|
||||
if (setFolders)
|
||||
{
|
||||
PhysicalFolderIds = newFolderIds;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
private ItemResolveArgs CreateResolveArgs(IDirectoryService directoryService, bool setPhysicalLocations)
|
||||
{
|
||||
var path = ContainingFolderPath;
|
||||
|
||||
var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService)
|
||||
{
|
||||
FileInfo = FileSystem.GetDirectoryInfo(path),
|
||||
Path = path,
|
||||
Parent = GetParent() as Folder,
|
||||
CollectionType = CollectionType
|
||||
};
|
||||
|
||||
// Gather child folder and files
|
||||
if (args.IsDirectory)
|
||||
{
|
||||
var isPhysicalRoot = args.IsPhysicalRoot;
|
||||
|
||||
// When resolving the root, we need it's grandchildren (children of user views)
|
||||
var flattenFolderDepth = isPhysicalRoot ? 2 : 0;
|
||||
|
||||
var files = FileData.GetFilteredFileSystemEntries(directoryService, args.Path, FileSystem, Logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf);
|
||||
|
||||
// Need to remove subpaths that may have been resolved from shortcuts
|
||||
// Example: if \\server\movies exists, then strip out \\server\movies\action
|
||||
if (isPhysicalRoot)
|
||||
{
|
||||
files = LibraryManager.NormalizeRootPathList(files).ToArray();
|
||||
}
|
||||
|
||||
args.FileSystemChildren = files;
|
||||
}
|
||||
|
||||
_requiresRefresh = _requiresRefresh || !args.PhysicalLocations.SequenceEqual(PhysicalLocations);
|
||||
if (setPhysicalLocations)
|
||||
{
|
||||
PhysicalLocationsList = args.PhysicalLocations;
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare our current children (presumably just read from the repo) with the current state of the file system and adjust for any changes
|
||||
/// ***Currently does not contain logic to maintain items that are unavailable in the file system***
|
||||
/// </summary>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <param name="recursive">if set to <c>true</c> [recursive].</param>
|
||||
/// <param name="refreshChildMetadata">if set to <c>true</c> [refresh child metadata].</param>
|
||||
/// <param name="refreshOptions">The refresh options.</param>
|
||||
/// <param name="directoryService">The directory service.</param>
|
||||
/// <returns>Task.</returns>
|
||||
protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Our children are actually just references to the ones in the physical root...
|
||||
/// </summary>
|
||||
/// <value>The actual children.</value>
|
||||
[IgnoreDataMember]
|
||||
public override IEnumerable<BaseItem> Children
|
||||
{
|
||||
get { return GetActualChildren(); }
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> GetActualChildren()
|
||||
{
|
||||
return GetPhysicalFolders(true).SelectMany(c => c.Children);
|
||||
}
|
||||
|
||||
public IEnumerable<Folder> GetPhysicalFolders()
|
||||
{
|
||||
return GetPhysicalFolders(true);
|
||||
}
|
||||
|
||||
private IEnumerable<Folder> GetPhysicalFolders(bool enableCache)
|
||||
{
|
||||
if (enableCache)
|
||||
{
|
||||
return PhysicalFolderIds.Select(i => LibraryManager.GetItemById(i)).OfType<Folder>();
|
||||
}
|
||||
|
||||
var rootChildren = LibraryManager.RootFolder.Children
|
||||
.OfType<Folder>()
|
||||
.ToList();
|
||||
|
||||
return PhysicalLocations.Where(i => !FileSystem.AreEqual(i, Path)).SelectMany(i => GetPhysicalParents(i, rootChildren)).DistinctBy(i => i.Id);
|
||||
}
|
||||
|
||||
private IEnumerable<Folder> GetPhysicalParents(string path, List<Folder> rootChildren)
|
||||
{
|
||||
var result = rootChildren
|
||||
.Where(i => FileSystem.AreEqual(i.Path, path))
|
||||
.ToList();
|
||||
|
||||
if (result.Count == 0)
|
||||
{
|
||||
var folder = LibraryManager.FindByPath(path, true) as Folder;
|
||||
|
||||
if (folder != null)
|
||||
{
|
||||
result.Add(folder);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public static class DayOfWeekHelper
|
||||
{
|
||||
public static List<DayOfWeek> GetDaysOfWeek(DynamicDayOfWeek day)
|
||||
{
|
||||
return GetDaysOfWeek(new List<DynamicDayOfWeek> { day });
|
||||
}
|
||||
|
||||
public static List<DayOfWeek> GetDaysOfWeek(List<DynamicDayOfWeek> days)
|
||||
{
|
||||
var list = new List<DayOfWeek>();
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Sunday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekend) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Sunday);
|
||||
}
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Saturday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekend) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Saturday);
|
||||
}
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Monday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekday) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Monday);
|
||||
}
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Monday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekday) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Tuesday
|
||||
);
|
||||
}
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Wednesday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekday) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Wednesday);
|
||||
}
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Thursday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekday) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Thursday);
|
||||
}
|
||||
|
||||
if (days.Contains(DynamicDayOfWeek.Friday) ||
|
||||
days.Contains(DynamicDayOfWeek.Weekday) ||
|
||||
days.Contains(DynamicDayOfWeek.Everyday))
|
||||
{
|
||||
list.Add(DayOfWeek.Friday);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Extensions
|
||||
/// </summary>
|
||||
public static class Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the trailer URL.
|
||||
/// </summary>
|
||||
public static void AddTrailerUrl(this IHasTrailers item, string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
throw new ArgumentNullException("url");
|
||||
}
|
||||
|
||||
var current = item.RemoteTrailers.FirstOrDefault(i => string.Equals(i.Url, url, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (current == null)
|
||||
{
|
||||
var mediaUrl = new MediaUrl
|
||||
{
|
||||
Url = url
|
||||
};
|
||||
|
||||
if (item.RemoteTrailers.Length == 0)
|
||||
{
|
||||
item.RemoteTrailers = new[] { mediaUrl };
|
||||
}
|
||||
else
|
||||
{
|
||||
var list = item.RemoteTrailers.ToArray(item.RemoteTrailers.Length + 1);
|
||||
list[list.Length - 1] = mediaUrl;
|
||||
|
||||
item.RemoteTrailers = list;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,130 +0,0 @@
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class Game : BaseItem, IHasTrailers, IHasScreenshots, ISupportsPlaceHolders, IHasLookupInfo<GameInfo>
|
||||
{
|
||||
public Game()
|
||||
{
|
||||
MultiPartGameFiles = EmptyStringArray;
|
||||
RemoteTrailers = EmptyMediaUrlArray;
|
||||
LocalTrailerIds = EmptyGuidArray;
|
||||
RemoteTrailerIds = EmptyGuidArray;
|
||||
}
|
||||
|
||||
public Guid[] LocalTrailerIds { get; set; }
|
||||
public Guid[] RemoteTrailerIds { get; set; }
|
||||
|
||||
public override bool CanDownload()
|
||||
{
|
||||
var locationType = LocationType;
|
||||
return locationType != LocationType.Remote &&
|
||||
locationType != LocationType.Virtual;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsThemeMedia
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the remote trailers.
|
||||
/// </summary>
|
||||
/// <value>The remote trailers.</value>
|
||||
public MediaUrl[] RemoteTrailers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the media.
|
||||
/// </summary>
|
||||
/// <value>The type of the media.</value>
|
||||
[IgnoreDataMember]
|
||||
public override string MediaType
|
||||
{
|
||||
get { return Model.Entities.MediaType.Game; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the players supported.
|
||||
/// </summary>
|
||||
/// <value>The players supported.</value>
|
||||
public int? PlayersSupported { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is place holder.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is place holder; otherwise, <c>false</c>.</value>
|
||||
public bool IsPlaceHolder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the game system.
|
||||
/// </summary>
|
||||
/// <value>The game system.</value>
|
||||
public string GameSystem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is multi part.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is multi part; otherwise, <c>false</c>.</value>
|
||||
public bool IsMultiPart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds the paths to the game files in the event this is a multipart game
|
||||
/// </summary>
|
||||
public string[] MultiPartGameFiles { get; set; }
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
var id = this.GetProviderId(MetadataProviders.Gamesdb);
|
||||
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
{
|
||||
list.Insert(0, "Game-Gamesdb-" + id);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public override IEnumerable<FileSystemMetadata> GetDeletePaths()
|
||||
{
|
||||
if (!IsInMixedFolder)
|
||||
{
|
||||
return new[] {
|
||||
new FileSystemMetadata
|
||||
{
|
||||
FullName = FileSystem.GetDirectoryName(Path),
|
||||
IsDirectory = true
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return base.GetDeletePaths();
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Game;
|
||||
}
|
||||
|
||||
public GameInfo GetLookupInfo()
|
||||
{
|
||||
var id = GetItemLookupInfo<GameInfo>();
|
||||
|
||||
id.GameSystem = GameSystem;
|
||||
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class GameGenre : BaseItem, IItemByName
|
||||
{
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return GetUserDataKeys()[0];
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the folder containing the item.
|
||||
/// If the item is a folder, it returns the folder itself
|
||||
/// </summary>
|
||||
/// <value>The containing folder path.</value>
|
||||
[IgnoreDataMember]
|
||||
public override string ContainingFolderPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsAncestors
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is owned item.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
|
||||
[IgnoreDataMember]
|
||||
public override bool IsOwnedItem
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsSaveLocalMetadataEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
{
|
||||
query.GenreIds = new[] { Id.ToString("N") };
|
||||
query.IncludeItemTypes = new[] { typeof(Game).Name };
|
||||
|
||||
return LibraryManager.GetItemList(query);
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPath(string name)
|
||||
{
|
||||
return GetPath(name, true);
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validName = normalizeName ?
|
||||
FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
|
||||
name;
|
||||
|
||||
return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.GameGenrePath, validName);
|
||||
}
|
||||
|
||||
private string GetRebasedPath()
|
||||
{
|
||||
return GetPath(System.IO.Path.GetFileName(Path), false);
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Path = newPath;
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class GameSystem
|
||||
/// </summary>
|
||||
public class GameSystem : Folder, IHasLookupInfo<GameSystemInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Return the id that should be used to key display prefs for this item.
|
||||
/// Default is based on the type for everything except actual generic folders.
|
||||
/// </summary>
|
||||
/// <value>The display prefs id.</value>
|
||||
[IgnoreDataMember]
|
||||
public override Guid DisplayPreferencesId
|
||||
{
|
||||
get
|
||||
{
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPlayedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsInheritedParentImages
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
double value = 16;
|
||||
value /= 9;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the game system.
|
||||
/// </summary>
|
||||
/// <value>The game system.</value>
|
||||
public string GameSystemName { get; set; }
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
if (!string.IsNullOrEmpty(GameSystemName))
|
||||
{
|
||||
list.Insert(0, "GameSystem-" + GameSystemName);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
{
|
||||
// Don't block. Determine by game
|
||||
return false;
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Game;
|
||||
}
|
||||
|
||||
public GameSystemInfo GetLookupInfo()
|
||||
{
|
||||
var id = GetItemLookupInfo<GameSystemInfo>();
|
||||
|
||||
id.Path = Path;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Genre
|
||||
/// </summary>
|
||||
public class Genre : BaseItem, IItemByName
|
||||
{
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return GetUserDataKeys()[0];
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the folder containing the item.
|
||||
/// If the item is a folder, it returns the folder itself
|
||||
/// </summary>
|
||||
/// <value>The containing folder path.</value>
|
||||
[IgnoreDataMember]
|
||||
public override string ContainingFolderPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool IsDisplayedAsFolder
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsAncestors
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsSaveLocalMetadataEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is owned item.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
|
||||
[IgnoreDataMember]
|
||||
public override bool IsOwnedItem
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
{
|
||||
query.GenreIds = new[] { Id.ToString("N") };
|
||||
query.ExcludeItemTypes = new[] { typeof(Game).Name, typeof(MusicVideo).Name, typeof(Audio.Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name };
|
||||
|
||||
return LibraryManager.GetItemList(query);
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPath(string name)
|
||||
{
|
||||
return GetPath(name, true);
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validName = normalizeName ?
|
||||
FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
|
||||
name;
|
||||
|
||||
return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.GenrePath, validName);
|
||||
}
|
||||
|
||||
private string GetRebasedPath()
|
||||
{
|
||||
return GetPath(System.IO.Path.GetFileName(Path), false);
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Path = newPath;
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// This is just a marker interface to denote top level folders
|
||||
/// </summary>
|
||||
public interface ICollectionFolder
|
||||
{
|
||||
string CollectionType { get; }
|
||||
string Path { get; }
|
||||
string Name { get; }
|
||||
Guid Id { get; }
|
||||
string[] PhysicalLocations { get; }
|
||||
}
|
||||
|
||||
public interface ISupportsUserSpecificView
|
||||
{
|
||||
bool EnableUserSpecificView { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IHasAspectRatio
|
||||
/// </summary>
|
||||
public interface IHasAspectRatio
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the aspect ratio.
|
||||
/// </summary>
|
||||
/// <value>The aspect ratio.</value>
|
||||
string AspectRatio { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IHasDisplayOrder
|
||||
/// </summary>
|
||||
public interface IHasDisplayOrder
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the display order.
|
||||
/// </summary>
|
||||
/// <value>The display order.</value>
|
||||
string DisplayOrder { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using MediaBrowser.Model.Dto;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHasMediaSources : IHasMetadata
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the media sources.
|
||||
/// </summary>
|
||||
/// <param name="enablePathSubstitution">if set to <c>true</c> [enable path substitution].</param>
|
||||
/// <returns>Task{IEnumerable{MediaSourceInfo}}.</returns>
|
||||
List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution);
|
||||
List<MediaStream> GetMediaStreams();
|
||||
}
|
||||
}
|
||||
@@ -1,317 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IHasMetadata
|
||||
/// </summary>
|
||||
public interface IHasMetadata : IHasProviderIds, IHasUserData
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the preferred metadata country code.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
string GetPreferredMetadataCountryCode();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the date modified.
|
||||
/// </summary>
|
||||
/// <value>The date modified.</value>
|
||||
DateTime DateModified { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date last saved.
|
||||
/// </summary>
|
||||
/// <value>The date last saved.</value>
|
||||
DateTime DateLastSaved { get; set; }
|
||||
|
||||
SourceType SourceType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date last refreshed.
|
||||
/// </summary>
|
||||
/// <value>The date last refreshed.</value>
|
||||
DateTime DateLastRefreshed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
bool BeforeMetadataRefresh();
|
||||
|
||||
/// <summary>
|
||||
/// Afters the metadata refresh.
|
||||
/// </summary>
|
||||
void AfterMetadataRefresh();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether [supports people].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [supports people]; otherwise, <c>false</c>.</value>
|
||||
bool SupportsPeople { get; }
|
||||
|
||||
bool RequiresRefresh();
|
||||
|
||||
bool EnableRefreshOnDateModifiedChange { get; }
|
||||
|
||||
string PresentationUniqueKey { get; set; }
|
||||
|
||||
string GetPresentationUniqueKey();
|
||||
string CreatePresentationUniqueKey();
|
||||
bool StopRefreshIfLocalMetadataFound { get; }
|
||||
|
||||
int? GetInheritedParentalRatingValue();
|
||||
int InheritedParentalRatingValue { get; set; }
|
||||
List<string> GetInheritedTags();
|
||||
long? RunTimeTicks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path.
|
||||
/// </summary>
|
||||
/// <value>The path.</value>
|
||||
string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file name without extension.
|
||||
/// </summary>
|
||||
/// <value>The file name without extension.</value>
|
||||
string FileNameWithoutExtension { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the location.
|
||||
/// </summary>
|
||||
/// <value>The type of the location.</value>
|
||||
LocationType LocationType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the locked fields.
|
||||
/// </summary>
|
||||
/// <value>The locked fields.</value>
|
||||
MetadataFields[] LockedFields { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the images.
|
||||
/// </summary>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <returns>IEnumerable{ItemImageInfo}.</returns>
|
||||
IEnumerable<ItemImageInfo> GetImages(ImageType imageType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image path.
|
||||
/// </summary>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <param name="imageIndex">Index of the image.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
string GetImagePath(ImageType imageType, int imageIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image information.
|
||||
/// </summary>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <param name="imageIndex">Index of the image.</param>
|
||||
/// <returns>ItemImageInfo.</returns>
|
||||
ItemImageInfo GetImageInfo(ImageType imageType, int imageIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the image.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <param name="file">The file.</param>
|
||||
void SetImagePath(ImageType type, int index, FileSystemMetadata file);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified type has image.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="imageIndex">Index of the image.</param>
|
||||
/// <returns><c>true</c> if the specified type has image; otherwise, <c>false</c>.</returns>
|
||||
bool HasImage(ImageType type, int imageIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Allowses the multiple images.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
bool AllowsMultipleImages(ImageType type);
|
||||
|
||||
/// <summary>
|
||||
/// Swaps the images.
|
||||
/// </summary>
|
||||
void SwapImages(ImageType type, int index1, int index2);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the primary image path.
|
||||
/// </summary>
|
||||
/// <value>The primary image path.</value>
|
||||
string PrimaryImagePath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the preferred metadata language.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
string GetPreferredMetadataLanguage();
|
||||
|
||||
/// <summary>
|
||||
/// Validates the images and returns true or false indicating if any were removed.
|
||||
/// </summary>
|
||||
bool ValidateImages(IDirectoryService directoryService);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is owned item.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
|
||||
bool IsOwnedItem { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the containing folder path.
|
||||
/// </summary>
|
||||
/// <value>The containing folder path.</value>
|
||||
string ContainingFolderPath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds the images.
|
||||
/// </summary>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <param name="images">The images.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
bool AddImages(ImageType imageType, List<FileSystemMetadata> images);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [is save local metadata enabled].
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if [is save local metadata enabled]; otherwise, <c>false</c>.</returns>
|
||||
bool IsSaveLocalMetadataEnabled();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether [supports local metadata].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [supports local metadata]; otherwise, <c>false</c>.</value>
|
||||
bool SupportsLocalMetadata { get; }
|
||||
|
||||
bool IsInMixedFolder { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is locked.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is locked; otherwise, <c>false</c>.</value>
|
||||
bool IsLocked { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether [supports remote image downloading].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [supports remote image downloading]; otherwise, <c>false</c>.</value>
|
||||
bool SupportsRemoteImageDownloading { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the internal metadata path.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
string GetInternalMetadataPath();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether [always scan internal metadata path].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [always scan internal metadata path]; otherwise, <c>false</c>.</value>
|
||||
bool AlwaysScanInternalMetadataPath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [is internet metadata enabled].
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if [is internet metadata enabled]; otherwise, <c>false</c>.</returns>
|
||||
bool IsInternetMetadataEnabled();
|
||||
|
||||
/// <summary>
|
||||
/// Removes the image.
|
||||
/// </summary>
|
||||
/// <param name="image">The image.</param>
|
||||
void RemoveImage(ItemImageInfo image);
|
||||
|
||||
void RemoveImages(List<ItemImageInfo> images);
|
||||
|
||||
/// <summary>
|
||||
/// Updates to repository.
|
||||
/// </summary>
|
||||
void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the image.
|
||||
/// </summary>
|
||||
/// <param name="image">The image.</param>
|
||||
/// <param name="index">The index.</param>
|
||||
void SetImage(ItemImageInfo image, int index);
|
||||
|
||||
double? GetDefaultPrimaryImageAspectRatio();
|
||||
|
||||
int? ProductionYear { get; set; }
|
||||
|
||||
string[] Tags { get; set; }
|
||||
|
||||
ItemUpdateType OnMetadataChanged();
|
||||
}
|
||||
|
||||
public static class HasMetadataExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the image path.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
public static string GetImagePath(this IHasMetadata item, ImageType imageType)
|
||||
{
|
||||
return item.GetImagePath(imageType, 0);
|
||||
}
|
||||
|
||||
public static bool HasImage(this IHasMetadata item, ImageType imageType)
|
||||
{
|
||||
return item.HasImage(imageType, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the image path.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <param name="file">The file.</param>
|
||||
public static void SetImagePath(this IHasMetadata item, ImageType imageType, FileSystemMetadata file)
|
||||
{
|
||||
item.SetImagePath(imageType, 0, file);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the image path.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <param name="file">The file.</param>
|
||||
public static void SetImagePath(this IHasMetadata item, ImageType imageType, string file)
|
||||
{
|
||||
if (file.StartsWith("http", System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
item.SetImage(new ItemImageInfo
|
||||
{
|
||||
Path = file,
|
||||
Type = imageType
|
||||
}, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.SetImagePath(imageType, BaseItem.FileSystem.GetFileInfo(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHasProgramAttributes
|
||||
{
|
||||
bool IsMovie { get; set; }
|
||||
bool IsSports { get; set; }
|
||||
bool IsNews { get; set; }
|
||||
bool IsKids { get; set; }
|
||||
bool IsRepeat { get; set; }
|
||||
bool? IsHD { get; set; }
|
||||
bool IsSeries { get; set; }
|
||||
bool IsLive { get; set; }
|
||||
bool IsPremiere { get; set; }
|
||||
ProgramAudio? Audio { get; set; }
|
||||
string EpisodeTitle { get; set; }
|
||||
string ServiceName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IHasScreenshots
|
||||
/// </summary>
|
||||
public interface IHasScreenshots
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHasSeries
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the series.
|
||||
/// </summary>
|
||||
/// <value>The name of the series.</value>
|
||||
string SeriesName { get; set; }
|
||||
string FindSeriesName();
|
||||
string FindSeriesSortName();
|
||||
Guid? SeriesId { get; set; }
|
||||
Guid? FindSeriesId();
|
||||
string SeriesPresentationUniqueKey { get; set; }
|
||||
string FindSeriesPresentationUniqueKey();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHasSpecialFeatures
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the special feature ids.
|
||||
/// </summary>
|
||||
/// <value>The special feature ids.</value>
|
||||
Guid[] SpecialFeatureIds { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHasStartDate
|
||||
{
|
||||
DateTime StartDate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHasTrailers : IHasMetadata
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the remote trailers.
|
||||
/// </summary>
|
||||
/// <value>The remote trailers.</value>
|
||||
MediaUrl[] RemoteTrailers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the local trailer ids.
|
||||
/// </summary>
|
||||
/// <value>The local trailer ids.</value>
|
||||
Guid[] LocalTrailerIds { get; set; }
|
||||
Guid[] RemoteTrailerIds { get; set; }
|
||||
}
|
||||
|
||||
public static class HasTrailerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the trailer ids.
|
||||
/// </summary>
|
||||
/// <returns>List<Guid>.</returns>
|
||||
public static List<Guid> GetTrailerIds(this IHasTrailers item)
|
||||
{
|
||||
var list = item.LocalTrailerIds.ToList();
|
||||
list.AddRange(item.RemoteTrailerIds);
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IHasUserData
|
||||
/// </summary>
|
||||
public interface IHasUserData
|
||||
{
|
||||
List<string> GetUserDataKeys();
|
||||
|
||||
/// <summary>
|
||||
/// Fills the user data dto values.
|
||||
/// </summary>
|
||||
void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, ItemFields[] fields);
|
||||
|
||||
bool EnableRememberingTrackSelections { get; }
|
||||
|
||||
bool SupportsPlayedStatus { get; }
|
||||
|
||||
Guid Id { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHiddenFromDisplay
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the specified user is hidden.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns><c>true</c> if the specified user is hidden; otherwise, <c>false</c>.</returns>
|
||||
bool IsHiddenFromUser(User user);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Marker interface
|
||||
/// </summary>
|
||||
public interface IItemByName : IHasMetadata
|
||||
{
|
||||
IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query);
|
||||
}
|
||||
|
||||
public interface IHasDualAccess : IItemByName
|
||||
{
|
||||
bool IsAccessedByName { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IMetadataContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// Refreshes all metadata.
|
||||
/// </summary>
|
||||
/// <param name="refreshOptions">The refresh options.</param>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Marker interface to denote a class that supports being hidden underneath it's boxset.
|
||||
/// Just about anything can be placed into a boxset,
|
||||
/// but movies should also only appear underneath and not outside separately (subject to configuration).
|
||||
/// </summary>
|
||||
public interface ISupportsBoxSetGrouping
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface ISupportsPlaceHolders
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is place holder.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is place holder; otherwise, <c>false</c>.</value>
|
||||
bool IsPlaceHolder { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IVirtualFolderCreator
|
||||
/// </summary>
|
||||
public interface IVirtualFolderCreator
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the folder.
|
||||
/// </summary>
|
||||
/// <returns>Folder.</returns>
|
||||
BasePluginFolder GetFolder();
|
||||
}
|
||||
}
|
||||
@@ -1,243 +0,0 @@
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class InternalItemsQuery
|
||||
{
|
||||
public bool Recursive { get; set; }
|
||||
|
||||
public int? StartIndex { get; set; }
|
||||
|
||||
public int? Limit { get; set; }
|
||||
|
||||
public User User { get; set; }
|
||||
|
||||
public BaseItem SimilarTo { get; set; }
|
||||
|
||||
public bool? IsFolder { get; set; }
|
||||
public bool? IsFavorite { get; set; }
|
||||
public bool? IsFavoriteOrLiked { get; set; }
|
||||
public bool? IsLiked { get; set; }
|
||||
public bool? IsPlayed { get; set; }
|
||||
public bool? IsResumable { get; set; }
|
||||
public bool? IncludeItemsByName { get; set; }
|
||||
|
||||
public string[] MediaTypes { get; set; }
|
||||
public string[] IncludeItemTypes { get; set; }
|
||||
public string[] ExcludeItemTypes { get; set; }
|
||||
public string[] ExcludeTags { get; set; }
|
||||
public string[] ExcludeInheritedTags { get; set; }
|
||||
public string[] Genres { get; set; }
|
||||
|
||||
public bool? IsSpecialSeason { get; set; }
|
||||
public bool? IsMissing { get; set; }
|
||||
public bool? IsUnaired { get; set; }
|
||||
public bool? CollapseBoxSetItems { get; set; }
|
||||
|
||||
public string NameStartsWithOrGreater { get; set; }
|
||||
public string NameStartsWith { get; set; }
|
||||
public string NameLessThan { get; set; }
|
||||
public string NameContains { get; set; }
|
||||
public string MinSortName { get; set; }
|
||||
|
||||
public string PresentationUniqueKey { get; set; }
|
||||
public string Path { get; set; }
|
||||
public string PathNotStartsWith { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Person { get; set; }
|
||||
public string[] PersonIds { get; set; }
|
||||
public string[] ItemIds { get; set; }
|
||||
public string[] ExcludeItemIds { get; set; }
|
||||
public string AdjacentTo { get; set; }
|
||||
public string[] PersonTypes { get; set; }
|
||||
|
||||
public bool? Is3D { get; set; }
|
||||
public bool? IsHD { get; set; }
|
||||
public bool? IsInBoxSet { get; set; }
|
||||
public bool? IsLocked { get; set; }
|
||||
public bool? IsPlaceHolder { get; set; }
|
||||
|
||||
public bool? HasImdbId { get; set; }
|
||||
public bool? HasOverview { get; set; }
|
||||
public bool? HasTmdbId { get; set; }
|
||||
public bool? HasOfficialRating { get; set; }
|
||||
public bool? HasTvdbId { get; set; }
|
||||
public bool? HasThemeSong { get; set; }
|
||||
public bool? HasThemeVideo { get; set; }
|
||||
public bool? HasSubtitles { get; set; }
|
||||
public bool? HasSpecialFeature { get; set; }
|
||||
public bool? HasTrailer { get; set; }
|
||||
public bool? HasParentalRating { get; set; }
|
||||
|
||||
public string[] StudioIds { get; set; }
|
||||
public string[] GenreIds { get; set; }
|
||||
public ImageType[] ImageTypes { get; set; }
|
||||
public VideoType[] VideoTypes { get; set; }
|
||||
public UnratedItem[] BlockUnratedItems { get; set; }
|
||||
public int[] Years { get; set; }
|
||||
public string[] Tags { get; set; }
|
||||
public string[] OfficialRatings { get; set; }
|
||||
|
||||
public DateTime? MinPremiereDate { get; set; }
|
||||
public DateTime? MaxPremiereDate { get; set; }
|
||||
public DateTime? MinStartDate { get; set; }
|
||||
public DateTime? MaxStartDate { get; set; }
|
||||
public DateTime? MinEndDate { get; set; }
|
||||
public DateTime? MaxEndDate { get; set; }
|
||||
public bool? IsAiring { get; set; }
|
||||
|
||||
public bool? IsMovie { get; set; }
|
||||
public bool? IsSports { get; set; }
|
||||
public bool? IsKids { get; set; }
|
||||
public bool? IsNews { get; set; }
|
||||
public bool? IsSeries { get; set; }
|
||||
|
||||
public int? MinPlayers { get; set; }
|
||||
public int? MaxPlayers { get; set; }
|
||||
public int? MinIndexNumber { get; set; }
|
||||
public int? AiredDuringSeason { get; set; }
|
||||
public double? MinCriticRating { get; set; }
|
||||
public double? MinCommunityRating { get; set; }
|
||||
|
||||
public string[] ChannelIds { get; set; }
|
||||
|
||||
internal List<Guid> ItemIdsFromPersonFilters { get; set; }
|
||||
public int? ParentIndexNumber { get; set; }
|
||||
public int? ParentIndexNumberNotEquals { get; set; }
|
||||
public int? IndexNumber { get; set; }
|
||||
public int? MinParentalRating { get; set; }
|
||||
public int? MaxParentalRating { get; set; }
|
||||
|
||||
public bool? HasDeadParentId { get; set; }
|
||||
public bool? IsVirtualItem { get; set; }
|
||||
|
||||
public Guid? ParentId { get; set; }
|
||||
public string ParentType { get; set; }
|
||||
public string[] AncestorIds { get; set; }
|
||||
public string[] TopParentIds { get; set; }
|
||||
|
||||
public BaseItem Parent
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
ParentId = null;
|
||||
ParentType = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParentId = value.Id;
|
||||
ParentType = value.GetType().Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string[] PresetViews { get; set; }
|
||||
public TrailerType[] TrailerTypes { get; set; }
|
||||
public SourceType[] SourceTypes { get; set; }
|
||||
|
||||
public SeriesStatus[] SeriesStatuses { get; set; }
|
||||
public string ExternalSeriesId { get; set; }
|
||||
public string ExternalId { get; set; }
|
||||
|
||||
public string[] AlbumIds { get; set; }
|
||||
public string[] ArtistIds { get; set; }
|
||||
public string[] ExcludeArtistIds { get; set; }
|
||||
public string AncestorWithPresentationUniqueKey { get; set; }
|
||||
public string SeriesPresentationUniqueKey { get; set; }
|
||||
|
||||
public bool GroupByPresentationUniqueKey { get; set; }
|
||||
public bool GroupBySeriesPresentationUniqueKey { get; set; }
|
||||
public bool EnableTotalRecordCount { get; set; }
|
||||
public bool ForceDirect { get; set; }
|
||||
public Dictionary<string, string> ExcludeProviderIds { get; set; }
|
||||
public bool EnableGroupByMetadataKey { get; set; }
|
||||
public bool? HasChapterImages { get; set; }
|
||||
|
||||
public Tuple<string, SortOrder>[] OrderBy { get; set; }
|
||||
|
||||
public DateTime? MinDateCreated { get; set; }
|
||||
public DateTime? MinDateLastSaved { get; set; }
|
||||
public DateTime? MinDateLastSavedForUser { get; set; }
|
||||
|
||||
public DtoOptions DtoOptions { get; set; }
|
||||
public int MinSimilarityScore { get; set; }
|
||||
public string HasNoAudioTrackWithLanguage { get; set; }
|
||||
public string HasNoInternalSubtitleTrackWithLanguage { get; set; }
|
||||
public string HasNoExternalSubtitleTrackWithLanguage { get; set; }
|
||||
public string HasNoSubtitleTrackWithLanguage { get; set; }
|
||||
|
||||
public InternalItemsQuery()
|
||||
{
|
||||
MinSimilarityScore = 20;
|
||||
|
||||
GroupByPresentationUniqueKey = true;
|
||||
EnableTotalRecordCount = true;
|
||||
|
||||
DtoOptions = new DtoOptions();
|
||||
AlbumIds = new string[] { };
|
||||
ArtistIds = new string[] { };
|
||||
ExcludeArtistIds = new string[] { };
|
||||
ExcludeProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
BlockUnratedItems = new UnratedItem[] { };
|
||||
Tags = new string[] { };
|
||||
OfficialRatings = new string[] { };
|
||||
MediaTypes = new string[] { };
|
||||
IncludeItemTypes = new string[] { };
|
||||
ExcludeItemTypes = new string[] { };
|
||||
Genres = new string[] { };
|
||||
StudioIds = new string[] { };
|
||||
GenreIds = new string[] { };
|
||||
ImageTypes = new ImageType[] { };
|
||||
VideoTypes = new VideoType[] { };
|
||||
Years = new int[] { };
|
||||
PersonTypes = new string[] { };
|
||||
PersonIds = new string[] { };
|
||||
ChannelIds = new string[] { };
|
||||
ItemIds = new string[] { };
|
||||
ExcludeItemIds = new string[] { };
|
||||
AncestorIds = new string[] { };
|
||||
TopParentIds = new string[] { };
|
||||
ExcludeTags = new string[] { };
|
||||
ExcludeInheritedTags = new string[] { };
|
||||
PresetViews = new string[] { };
|
||||
TrailerTypes = new TrailerType[] { };
|
||||
SourceTypes = new SourceType[] { };
|
||||
SeriesStatuses = new SeriesStatus[] { };
|
||||
OrderBy = new Tuple<string, SortOrder>[] { };
|
||||
}
|
||||
|
||||
public InternalItemsQuery(User user)
|
||||
: this()
|
||||
{
|
||||
SetUser(user);
|
||||
}
|
||||
|
||||
public void SetUser(User user)
|
||||
{
|
||||
if (user != null)
|
||||
{
|
||||
var policy = user.Policy;
|
||||
MaxParentalRating = policy.MaxParentalRating;
|
||||
|
||||
if (policy.MaxParentalRating.HasValue)
|
||||
{
|
||||
BlockUnratedItems = policy.BlockUnratedItems.Where(i => i != UnratedItem.Other).ToArray();
|
||||
}
|
||||
|
||||
ExcludeInheritedTags = policy.BlockedTags;
|
||||
|
||||
User = user;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class InternalPeopleQuery
|
||||
{
|
||||
public Guid ItemId { get; set; }
|
||||
public string[] PersonTypes { get; set; }
|
||||
public List<string> ExcludePersonTypes { get; set; }
|
||||
public int? MaxListOrder { get; set; }
|
||||
public Guid AppearsInItemId { get; set; }
|
||||
public string NameContains { get; set; }
|
||||
|
||||
public InternalPeopleQuery()
|
||||
{
|
||||
PersonTypes = new string[] {};
|
||||
ExcludePersonTypes = new List<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class ItemImageInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the path.
|
||||
/// </summary>
|
||||
/// <value>The path.</value>
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type.
|
||||
/// </summary>
|
||||
/// <value>The type.</value>
|
||||
public ImageType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date modified.
|
||||
/// </summary>
|
||||
/// <value>The date modified.</value>
|
||||
public DateTime DateModified { get; set; }
|
||||
|
||||
public int Width { get; set; }
|
||||
public int Height { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool IsLocalFile
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Path != null)
|
||||
{
|
||||
if (Path.StartsWith("http", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class LinkedChild
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public LinkedChildType Type { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Serves as a cache
|
||||
/// </summary>
|
||||
public Guid? ItemId { get; set; }
|
||||
|
||||
public static LinkedChild Create(BaseItem item)
|
||||
{
|
||||
return new LinkedChild
|
||||
{
|
||||
Path = item.Path,
|
||||
Type = LinkedChildType.Manual
|
||||
};
|
||||
}
|
||||
|
||||
public LinkedChild()
|
||||
{
|
||||
Id = Guid.NewGuid().ToString("N");
|
||||
}
|
||||
}
|
||||
|
||||
public enum LinkedChildType
|
||||
{
|
||||
Manual = 0,
|
||||
Shortcut = 1
|
||||
}
|
||||
|
||||
public class LinkedChildComparer : IEqualityComparer<LinkedChild>
|
||||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public LinkedChildComparer(IFileSystem fileSystem)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
public bool Equals(LinkedChild x, LinkedChild y)
|
||||
{
|
||||
if (x.Type == y.Type)
|
||||
{
|
||||
return _fileSystem.AreEqual(x.Path, y.Path);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int GetHashCode(LinkedChild obj)
|
||||
{
|
||||
return (obj.Path + obj.Type).GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Movies
|
||||
{
|
||||
/// <summary>
|
||||
/// Class BoxSet
|
||||
/// </summary>
|
||||
public class BoxSet : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<BoxSetInfo>, IHasShares
|
||||
{
|
||||
public List<Share> Shares { get; set; }
|
||||
|
||||
public BoxSet()
|
||||
{
|
||||
RemoteTrailers = EmptyMediaUrlArray;
|
||||
LocalTrailerIds = EmptyGuidArray;
|
||||
RemoteTrailerIds = EmptyGuidArray;
|
||||
|
||||
DisplayOrder = ItemSortBy.PremiereDate;
|
||||
Shares = new List<Share>();
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
protected override bool FilterLinkedChildrenPerUser
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsInheritedParentImages
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public Guid[] LocalTrailerIds { get; set; }
|
||||
public Guid[] RemoteTrailerIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the remote trailers.
|
||||
/// </summary>
|
||||
/// <value>The remote trailers.</value>
|
||||
public MediaUrl[] RemoteTrailers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display order.
|
||||
/// </summary>
|
||||
/// <value>The display order.</value>
|
||||
public string DisplayOrder { get; set; }
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
{
|
||||
return config.BlockUnratedItems.Contains(UnratedItem.Movie);
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
double value = 2;
|
||||
value /= 3;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Movie;
|
||||
}
|
||||
|
||||
protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
|
||||
{
|
||||
if (IsLegacyBoxSet)
|
||||
{
|
||||
return base.GetNonCachedChildren(directoryService);
|
||||
}
|
||||
return new List<BaseItem>();
|
||||
}
|
||||
|
||||
protected override List<BaseItem> LoadChildren()
|
||||
{
|
||||
if (IsLegacyBoxSet)
|
||||
{
|
||||
return base.LoadChildren();
|
||||
}
|
||||
|
||||
// Save a trip to the database
|
||||
return new List<BaseItem>();
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
private bool IsLegacyBoxSet
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Path))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LinkedChildren.Length > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !FileSystem.ContainsSubPath(ConfigurationManager.ApplicationPaths.DataPath, Path);
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool IsPreSorted
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool IsSaveLocalMetadataEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the official rating based on content and returns true or false indicating if it changed.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool UpdateRatingToContent()
|
||||
{
|
||||
var currentOfficialRating = OfficialRating;
|
||||
|
||||
// Gather all possible ratings
|
||||
var ratings = GetLinkedChildren()
|
||||
.Select(i => i.OfficialRating)
|
||||
.Where(i => !string.IsNullOrEmpty(i))
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.Select(i => new Tuple<string, int?>(i, LocalizationManager.GetRatingLevel(i)))
|
||||
.OrderBy(i => i.Item2 ?? 1000)
|
||||
.Select(i => i.Item1);
|
||||
|
||||
OfficialRating = ratings.FirstOrDefault() ?? currentOfficialRating;
|
||||
|
||||
return !string.Equals(currentOfficialRating ?? string.Empty, OfficialRating ?? string.Empty,
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
|
||||
{
|
||||
var children = base.GetChildren(user, includeLinkedChildren);
|
||||
|
||||
if (string.Equals(DisplayOrder, ItemSortBy.SortName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Sort by name
|
||||
return LibraryManager.Sort(children, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).ToList();
|
||||
}
|
||||
|
||||
if (string.Equals(DisplayOrder, ItemSortBy.PremiereDate, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Sort by release date
|
||||
return LibraryManager.Sort(children, user, new[] { ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName }, SortOrder.Ascending).ToList();
|
||||
}
|
||||
|
||||
// Default sorting
|
||||
return LibraryManager.Sort(children, user, new[] { ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName }, SortOrder.Ascending).ToList();
|
||||
}
|
||||
|
||||
public BoxSetInfo GetLookupInfo()
|
||||
{
|
||||
return GetItemLookupInfo<BoxSetInfo>();
|
||||
}
|
||||
|
||||
public override bool IsVisible(User user)
|
||||
{
|
||||
var userId = user.Id.ToString("N");
|
||||
|
||||
// Need to check Count > 0 for boxsets created prior to the introduction of Shares
|
||||
if (Shares.Count > 0 && Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (base.IsVisible(user))
|
||||
{
|
||||
return base.GetChildren(user, true).Count > 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsVisibleStandalone(User user)
|
||||
{
|
||||
return IsVisible(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.Movies
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Movie
|
||||
/// </summary>
|
||||
public class Movie : Video, IHasSpecialFeatures, IHasTrailers, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping
|
||||
{
|
||||
public Guid[] SpecialFeatureIds { get; set; }
|
||||
|
||||
public Movie()
|
||||
{
|
||||
SpecialFeatureIds = EmptyGuidArray;
|
||||
RemoteTrailers = EmptyMediaUrlArray;
|
||||
LocalTrailerIds = EmptyGuidArray;
|
||||
RemoteTrailerIds = EmptyGuidArray;
|
||||
}
|
||||
|
||||
public Guid[] LocalTrailerIds { get; set; }
|
||||
public Guid[] RemoteTrailerIds { get; set; }
|
||||
|
||||
public MediaUrl[] RemoteTrailers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the TMDB collection.
|
||||
/// </summary>
|
||||
/// <value>The name of the TMDB collection.</value>
|
||||
public string TmdbCollectionName { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string CollectionName
|
||||
{
|
||||
get { return TmdbCollectionName; }
|
||||
set { TmdbCollectionName = value; }
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
double value = 2;
|
||||
value /= 3;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
|
||||
{
|
||||
var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Must have a parent to have special features
|
||||
// In other words, it must be part of the Parent/Child tree
|
||||
if (LocationType == LocationType.FileSystem && GetParent() != null && !IsInMixedFolder)
|
||||
{
|
||||
var specialFeaturesChanged = await RefreshSpecialFeatures(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (specialFeaturesChanged)
|
||||
{
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
private async Task<bool> RefreshSpecialFeatures(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
|
||||
{
|
||||
var newItems = LibraryManager.FindExtras(this, fileSystemChildren, options.DirectoryService).ToList();
|
||||
var newItemIds = newItems.Select(i => i.Id).ToArray();
|
||||
|
||||
var itemsChanged = !SpecialFeatureIds.SequenceEqual(newItemIds);
|
||||
|
||||
var ownerId = Id;
|
||||
|
||||
var tasks = newItems.Select(i =>
|
||||
{
|
||||
var subOptions = new MetadataRefreshOptions(options);
|
||||
|
||||
if (i.OwnerId != ownerId)
|
||||
{
|
||||
i.OwnerId = ownerId;
|
||||
subOptions.ForceSave = true;
|
||||
}
|
||||
|
||||
return RefreshMetadataForOwnedItem(i, false, subOptions, cancellationToken);
|
||||
});
|
||||
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
|
||||
SpecialFeatureIds = newItemIds;
|
||||
|
||||
return itemsChanged;
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Movie;
|
||||
}
|
||||
|
||||
public MovieInfo GetLookupInfo()
|
||||
{
|
||||
var info = GetItemLookupInfo<MovieInfo>();
|
||||
|
||||
if (!IsInMixedFolder)
|
||||
{
|
||||
var name = System.IO.Path.GetFileName(ContainingFolderPath);
|
||||
|
||||
if (VideoType == VideoType.VideoFile || VideoType == VideoType.Iso)
|
||||
{
|
||||
if (string.Equals(name, System.IO.Path.GetFileName(Path), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// if the folder has the file extension, strip it
|
||||
name = System.IO.Path.GetFileNameWithoutExtension(name);
|
||||
}
|
||||
}
|
||||
|
||||
info.Name = name;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
if (!ProductionYear.HasValue)
|
||||
{
|
||||
var info = LibraryManager.ParseName(Name);
|
||||
|
||||
var yearInName = info.Year;
|
||||
|
||||
if (yearInName.HasValue)
|
||||
{
|
||||
ProductionYear = yearInName;
|
||||
hasChanges = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to get the year from the folder name
|
||||
if (!IsInMixedFolder)
|
||||
{
|
||||
info = LibraryManager.ParseName(System.IO.Path.GetFileName(ContainingFolderPath));
|
||||
|
||||
yearInName = info.Year;
|
||||
|
||||
if (yearInName.HasValue)
|
||||
{
|
||||
ProductionYear = yearInName;
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
public override List<ExternalUrl> GetRelatedUrls()
|
||||
{
|
||||
var list = base.GetRelatedUrls();
|
||||
|
||||
var imdbId = this.GetProviderId(MetadataProviders.Imdb);
|
||||
if (!string.IsNullOrWhiteSpace(imdbId))
|
||||
{
|
||||
list.Add(new ExternalUrl
|
||||
{
|
||||
Name = "Trakt",
|
||||
Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool StopRefreshIfLocalMetadataFound
|
||||
{
|
||||
get
|
||||
{
|
||||
// Need people id's from internet metadata
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasLookupInfo<MusicVideoInfo>
|
||||
{
|
||||
[IgnoreDataMember]
|
||||
public string[] Artists { get; set; }
|
||||
|
||||
public MusicVideo()
|
||||
{
|
||||
Artists = EmptyStringArray;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string[] AllArtists
|
||||
{
|
||||
get
|
||||
{
|
||||
return Artists;
|
||||
}
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Music;
|
||||
}
|
||||
|
||||
public MusicVideoInfo GetLookupInfo()
|
||||
{
|
||||
return GetItemLookupInfo<MusicVideoInfo>();
|
||||
}
|
||||
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
if (!ProductionYear.HasValue)
|
||||
{
|
||||
var info = LibraryManager.ParseName(Name);
|
||||
|
||||
var yearInName = info.Year;
|
||||
|
||||
if (yearInName.HasValue)
|
||||
{
|
||||
ProductionYear = yearInName;
|
||||
hasChanges = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to get the year from the folder name
|
||||
if (!IsInMixedFolder)
|
||||
{
|
||||
info = LibraryManager.ParseName(System.IO.Path.GetFileName(ContainingFolderPath));
|
||||
|
||||
yearInName = info.Year;
|
||||
|
||||
if (yearInName.HasValue)
|
||||
{
|
||||
ProductionYear = yearInName;
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public static class PeopleHelper
|
||||
{
|
||||
public static void AddPerson(List<PersonInfo> people, PersonInfo person)
|
||||
{
|
||||
if (person == null)
|
||||
{
|
||||
throw new ArgumentNullException("person");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(person.Name))
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
// Normalize
|
||||
if (string.Equals(person.Role, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
person.Type = PersonType.GuestStar;
|
||||
}
|
||||
else if (string.Equals(person.Role, PersonType.Director, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
person.Type = PersonType.Director;
|
||||
}
|
||||
else if (string.Equals(person.Role, PersonType.Producer, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
person.Type = PersonType.Producer;
|
||||
}
|
||||
else if (string.Equals(person.Role, PersonType.Writer, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
person.Type = PersonType.Writer;
|
||||
}
|
||||
|
||||
// If the type is GuestStar and there's already an Actor entry, then update it to avoid dupes
|
||||
if (string.Equals(person.Type, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var existing = people.FirstOrDefault(p => p.Name.Equals(person.Name, StringComparison.OrdinalIgnoreCase) && p.Type.Equals(PersonType.Actor, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (existing != null)
|
||||
{
|
||||
existing.Type = PersonType.GuestStar;
|
||||
MergeExisting(existing, person);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.Equals(person.Type, PersonType.Actor, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// If the actor already exists without a role and we have one, fill it in
|
||||
var existing = people.FirstOrDefault(p => p.Name.Equals(person.Name, StringComparison.OrdinalIgnoreCase) && (p.Type.Equals(PersonType.Actor, StringComparison.OrdinalIgnoreCase) || p.Type.Equals(PersonType.GuestStar, StringComparison.OrdinalIgnoreCase)));
|
||||
if (existing == null)
|
||||
{
|
||||
// Wasn't there - add it
|
||||
people.Add(person);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Was there, if no role and we have one - fill it in
|
||||
if (string.IsNullOrWhiteSpace(existing.Role) && !string.IsNullOrWhiteSpace(person.Role))
|
||||
{
|
||||
existing.Role = person.Role;
|
||||
}
|
||||
|
||||
MergeExisting(existing, person);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var existing = people.FirstOrDefault(p =>
|
||||
string.Equals(p.Name, person.Name, StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(p.Type, person.Type, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// Check for dupes based on the combination of Name and Type
|
||||
if (existing == null)
|
||||
{
|
||||
people.Add(person);
|
||||
}
|
||||
else
|
||||
{
|
||||
MergeExisting(existing, person);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void MergeExisting(PersonInfo existing, PersonInfo person)
|
||||
{
|
||||
existing.SortOrder = person.SortOrder ?? existing.SortOrder;
|
||||
existing.ImageUrl = person.ImageUrl ?? existing.ImageUrl;
|
||||
|
||||
foreach (var id in person.ProviderIds)
|
||||
{
|
||||
existing.SetProviderId(id.Key, id.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ContainsPerson(List<PersonInfo> people, string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw new ArgumentNullException("name");
|
||||
}
|
||||
|
||||
foreach (var i in people)
|
||||
{
|
||||
if (string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,229 +0,0 @@
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the full Person object that can be retrieved with all of it's data.
|
||||
/// </summary>
|
||||
public class Person : BaseItem, IItemByName, IHasLookupInfo<PersonLookupInfo>
|
||||
{
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return GetUserDataKeys()[0];
|
||||
}
|
||||
|
||||
public PersonLookupInfo GetLookupInfo()
|
||||
{
|
||||
return GetItemLookupInfo<PersonLookupInfo>();
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
double value = 2;
|
||||
value /= 3;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
{
|
||||
query.PersonIds = new[] { Id.ToString("N") };
|
||||
|
||||
return LibraryManager.GetItemList(query);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the folder containing the item.
|
||||
/// If the item is a folder, it returns the folder itself
|
||||
/// </summary>
|
||||
/// <value>The containing folder path.</value>
|
||||
[IgnoreDataMember]
|
||||
public override string ContainingFolderPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsSaveLocalMetadataEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool EnableAlphaNumericSorting
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is owned item.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
|
||||
[IgnoreDataMember]
|
||||
public override bool IsOwnedItem
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsAncestors
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPath(string name)
|
||||
{
|
||||
return GetPath(name, true);
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validFilename = normalizeName ?
|
||||
FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
|
||||
name;
|
||||
|
||||
string subFolderPrefix = null;
|
||||
|
||||
foreach (char c in validFilename)
|
||||
{
|
||||
if (char.IsLetterOrDigit(c))
|
||||
{
|
||||
subFolderPrefix = c.ToString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var path = ConfigurationManager.ApplicationPaths.PeoplePath;
|
||||
|
||||
return string.IsNullOrEmpty(subFolderPrefix) ?
|
||||
System.IO.Path.Combine(path, validFilename) :
|
||||
System.IO.Path.Combine(path, subFolderPrefix, validFilename);
|
||||
}
|
||||
|
||||
private string GetRebasedPath()
|
||||
{
|
||||
return GetPath(System.IO.Path.GetFileName(Path), false);
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Path = newPath;
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the small Person stub that is attached to BaseItems
|
||||
/// </summary>
|
||||
public class PersonInfo : IHasProviderIds
|
||||
{
|
||||
public PersonInfo()
|
||||
{
|
||||
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public Guid ItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the role.
|
||||
/// </summary>
|
||||
/// <value>The role.</value>
|
||||
public string Role { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the type.
|
||||
/// </summary>
|
||||
/// <value>The type.</value>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the sort order - ascending
|
||||
/// </summary>
|
||||
/// <value>The sort order.</value>
|
||||
public int? SortOrder { get; set; }
|
||||
|
||||
public string ImageUrl { get; set; }
|
||||
|
||||
public Dictionary<string, string> ProviderIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="System.String" /> that represents this instance.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
public bool IsType(string type)
|
||||
{
|
||||
return string.Equals(Type, type, StringComparison.OrdinalIgnoreCase) || string.Equals(Role, type, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class Photo : BaseItem
|
||||
{
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsLocalMetadata
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override string MediaType
|
||||
{
|
||||
get
|
||||
{
|
||||
return Model.Entities.MediaType.Photo;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override Folder LatestItemsIndexContainer
|
||||
{
|
||||
get
|
||||
{
|
||||
return AlbumEntity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[IgnoreDataMember]
|
||||
public PhotoAlbum AlbumEntity
|
||||
{
|
||||
get
|
||||
{
|
||||
var parents = GetParents();
|
||||
foreach (var parent in parents)
|
||||
{
|
||||
var photoAlbum = parent as PhotoAlbum;
|
||||
if (photoAlbum != null)
|
||||
{
|
||||
return photoAlbum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool EnableRefreshOnDateModifiedChange
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanDownload()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
if (Width.HasValue && Height.HasValue)
|
||||
{
|
||||
double width = Width.Value;
|
||||
double height = Height.Value;
|
||||
|
||||
if (Orientation.HasValue)
|
||||
{
|
||||
switch (Orientation.Value)
|
||||
{
|
||||
case ImageOrientation.LeftBottom:
|
||||
case ImageOrientation.LeftTop:
|
||||
case ImageOrientation.RightBottom:
|
||||
case ImageOrientation.RightTop:
|
||||
var temp = height;
|
||||
height = width;
|
||||
width = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
width /= Height.Value;
|
||||
return width;
|
||||
}
|
||||
|
||||
return base.GetDefaultPrimaryImageAspectRatio();
|
||||
}
|
||||
|
||||
public int? Width { get; set; }
|
||||
public int? Height { get; set; }
|
||||
public string CameraMake { get; set; }
|
||||
public string CameraModel { get; set; }
|
||||
public string Software { get; set; }
|
||||
public double? ExposureTime { get; set; }
|
||||
public double? FocalLength { get; set; }
|
||||
public ImageOrientation? Orientation { get; set; }
|
||||
public double? Aperture { get; set; }
|
||||
public double? ShutterSpeed { get; set; }
|
||||
|
||||
public double? Latitude { get; set; }
|
||||
public double? Longitude { get; set; }
|
||||
public double? Altitude { get; set; }
|
||||
public int? IsoSpeedRating { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class PhotoAlbum : Folder
|
||||
{
|
||||
[IgnoreDataMember]
|
||||
public override bool AlwaysScanInternalMetadataPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPlayedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsInheritedParentImages
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHasShares
|
||||
{
|
||||
List<Share> Shares { get; set; }
|
||||
}
|
||||
|
||||
public class Share
|
||||
{
|
||||
public string UserId { get; set; }
|
||||
public bool CanEdit { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public enum SourceType
|
||||
{
|
||||
Library = 0,
|
||||
Channel = 1,
|
||||
LiveTV = 2
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Studio
|
||||
/// </summary>
|
||||
public class Studio : BaseItem, IItemByName
|
||||
{
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
|
||||
return list;
|
||||
}
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
return GetUserDataKeys()[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the folder containing the item.
|
||||
/// If the item is a folder, it returns the folder itself
|
||||
/// </summary>
|
||||
/// <value>The containing folder path.</value>
|
||||
[IgnoreDataMember]
|
||||
public override string ContainingFolderPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool IsDisplayedAsFolder
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsAncestors
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
double value = 16;
|
||||
value /= 9;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsSaveLocalMetadataEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is owned item.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
|
||||
[IgnoreDataMember]
|
||||
public override bool IsOwnedItem
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
{
|
||||
query.StudioIds = new[] { Id.ToString("N") };
|
||||
|
||||
return LibraryManager.GetItemList(query);
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPath(string name)
|
||||
{
|
||||
return GetPath(name, true);
|
||||
}
|
||||
|
||||
public static string GetPath(string name, bool normalizeName)
|
||||
{
|
||||
// Trim the period at the end because windows will have a hard time with that
|
||||
var validName = normalizeName ?
|
||||
FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
|
||||
name;
|
||||
|
||||
return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.StudioPath, validName);
|
||||
}
|
||||
|
||||
private string GetRebasedPath()
|
||||
{
|
||||
return GetPath(System.IO.Path.GetFileName(Path), false);
|
||||
}
|
||||
|
||||
public override bool RequiresRefresh()
|
||||
{
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
|
||||
return true;
|
||||
}
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
var newPath = GetRebasedPath();
|
||||
if (!string.Equals(Path, newPath, StringComparison.Ordinal))
|
||||
{
|
||||
Path = newPath;
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,385 +0,0 @@
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Episode
|
||||
/// </summary>
|
||||
public class Episode : Video, IHasTrailers, IHasLookupInfo<EpisodeInfo>, IHasSeries
|
||||
{
|
||||
public Episode()
|
||||
{
|
||||
RemoteTrailers = EmptyMediaUrlArray;
|
||||
LocalTrailerIds = EmptyGuidArray;
|
||||
RemoteTrailerIds = EmptyGuidArray;
|
||||
}
|
||||
|
||||
public Guid[] LocalTrailerIds { get; set; }
|
||||
public Guid[] RemoteTrailerIds { get; set; }
|
||||
public MediaUrl[] RemoteTrailers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the season in which it aired.
|
||||
/// </summary>
|
||||
/// <value>The aired season.</value>
|
||||
public int? AirsBeforeSeasonNumber { get; set; }
|
||||
public int? AirsAfterSeasonNumber { get; set; }
|
||||
public int? AirsBeforeEpisodeNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the DVD season number.
|
||||
/// </summary>
|
||||
/// <value>The DVD season number.</value>
|
||||
public int? DvdSeasonNumber { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the DVD episode number.
|
||||
/// </summary>
|
||||
/// <value>The DVD episode number.</value>
|
||||
public float? DvdEpisodeNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the absolute episode number.
|
||||
/// </summary>
|
||||
/// <value>The absolute episode number.</value>
|
||||
public int? AbsoluteEpisodeNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is the ending episode number for double episodes.
|
||||
/// </summary>
|
||||
/// <value>The index number.</value>
|
||||
public int? IndexNumberEnd { get; set; }
|
||||
|
||||
public string FindSeriesSortName()
|
||||
{
|
||||
var series = Series;
|
||||
return series == null ? SeriesName : series.SortName;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
protected override bool SupportsOwnedItems
|
||||
{
|
||||
get
|
||||
{
|
||||
return IsStacked || MediaSourceCount > 1;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsInheritedParentImages
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public int? AiredSeasonNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return AirsAfterSeasonNumber ?? AirsBeforeSeasonNumber ?? ParentIndexNumber;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override Folder LatestItemsIndexContainer
|
||||
{
|
||||
get
|
||||
{
|
||||
return Series;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override Guid? DisplayParentId
|
||||
{
|
||||
get
|
||||
{
|
||||
return SeasonId;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
protected override bool EnableDefaultVideoUserDataKeys
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
double value = 16;
|
||||
value /= 9;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
var series = Series;
|
||||
if (series != null && ParentIndexNumber.HasValue && IndexNumber.HasValue)
|
||||
{
|
||||
var seriesUserDataKeys = series.GetUserDataKeys();
|
||||
var take = seriesUserDataKeys.Count;
|
||||
if (seriesUserDataKeys.Count > 1)
|
||||
{
|
||||
take--;
|
||||
}
|
||||
list.InsertRange(0, seriesUserDataKeys.Take(take).Select(i => i + ParentIndexNumber.Value.ToString("000") + IndexNumber.Value.ToString("000")));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This Episode's Series Instance
|
||||
/// </summary>
|
||||
/// <value>The series.</value>
|
||||
[IgnoreDataMember]
|
||||
public Series Series
|
||||
{
|
||||
get
|
||||
{
|
||||
var seriesId = SeriesId ?? FindSeriesId();
|
||||
return seriesId.HasValue ? (LibraryManager.GetItemById(seriesId.Value) as Series) : null;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public Season Season
|
||||
{
|
||||
get
|
||||
{
|
||||
var seasonId = SeasonId ?? FindSeasonId();
|
||||
return seasonId.HasValue ? (LibraryManager.GetItemById(seasonId.Value) as Season) : null;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool IsInSeasonFolder
|
||||
{
|
||||
get
|
||||
{
|
||||
return FindParent<Season>() != null;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string SeriesPresentationUniqueKey { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string SeriesName { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string SeasonName { get; set; }
|
||||
|
||||
public string FindSeriesPresentationUniqueKey()
|
||||
{
|
||||
var series = Series;
|
||||
return series == null ? null : series.PresentationUniqueKey;
|
||||
}
|
||||
|
||||
public string FindSeasonName()
|
||||
{
|
||||
var season = Season;
|
||||
|
||||
if (season == null)
|
||||
{
|
||||
if (ParentIndexNumber.HasValue)
|
||||
{
|
||||
return "Season " + ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
return "Season Unknown";
|
||||
}
|
||||
|
||||
return season.Name;
|
||||
}
|
||||
|
||||
public string FindSeriesName()
|
||||
{
|
||||
var series = Series;
|
||||
return series == null ? SeriesName : series.Name;
|
||||
}
|
||||
|
||||
public Guid? FindSeasonId()
|
||||
{
|
||||
var season = FindParent<Season>();
|
||||
|
||||
// Episodes directly in series folder
|
||||
if (season == null)
|
||||
{
|
||||
var series = Series;
|
||||
|
||||
if (series != null && ParentIndexNumber.HasValue)
|
||||
{
|
||||
var findNumber = ParentIndexNumber.Value;
|
||||
|
||||
season = series.Children
|
||||
.OfType<Season>()
|
||||
.FirstOrDefault(i => i.IndexNumber.HasValue && i.IndexNumber.Value == findNumber);
|
||||
}
|
||||
}
|
||||
|
||||
return season == null ? (Guid?)null : season.Id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the name of the sort.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateSortName()
|
||||
{
|
||||
return (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("000 - ") : "")
|
||||
+ (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [contains episode number] [the specified number].
|
||||
/// </summary>
|
||||
/// <param name="number">The number.</param>
|
||||
/// <returns><c>true</c> if [contains episode number] [the specified number]; otherwise, <c>false</c>.</returns>
|
||||
public bool ContainsEpisodeNumber(int number)
|
||||
{
|
||||
if (IndexNumber.HasValue)
|
||||
{
|
||||
if (IndexNumberEnd.HasValue)
|
||||
{
|
||||
return number >= IndexNumber.Value && number <= IndexNumberEnd.Value;
|
||||
}
|
||||
|
||||
return IndexNumber.Value == number;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsRemoteImageDownloading
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsMissingEpisode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool IsMissingEpisode
|
||||
{
|
||||
get
|
||||
{
|
||||
return LocationType == LocationType.Virtual;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public Guid? SeasonId { get; set; }
|
||||
[IgnoreDataMember]
|
||||
public Guid? SeriesId { get; set; }
|
||||
|
||||
public Guid? FindSeriesId()
|
||||
{
|
||||
var series = FindParent<Series>();
|
||||
return series == null ? (Guid?)null : series.Id;
|
||||
}
|
||||
|
||||
public override IEnumerable<Guid> GetAncestorIds()
|
||||
{
|
||||
var list = base.GetAncestorIds().ToList();
|
||||
|
||||
var seasonId = SeasonId;
|
||||
|
||||
if (seasonId.HasValue && !list.Contains(seasonId.Value))
|
||||
{
|
||||
list.Add(seasonId.Value);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public override IEnumerable<FileSystemMetadata> GetDeletePaths()
|
||||
{
|
||||
return new[] {
|
||||
new FileSystemMetadata
|
||||
{
|
||||
FullName = Path,
|
||||
IsDirectory = IsFolder
|
||||
}
|
||||
}.Concat(GetLocalMetadataFilesToDelete());
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Series;
|
||||
}
|
||||
|
||||
public EpisodeInfo GetLookupInfo()
|
||||
{
|
||||
var id = GetItemLookupInfo<EpisodeInfo>();
|
||||
|
||||
var series = Series;
|
||||
|
||||
if (series != null)
|
||||
{
|
||||
id.SeriesProviderIds = series.ProviderIds;
|
||||
}
|
||||
|
||||
id.IsMissingEpisode = IsMissingEpisode;
|
||||
id.IndexNumberEnd = IndexNumberEnd;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
try
|
||||
{
|
||||
if (LibraryManager.FillMissingEpisodeNumbersFromPath(this))
|
||||
{
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.ErrorException("Error in FillMissingEpisodeNumbersFromPath. Episode: {0}", ex, Path ?? Name ?? Id.ToString());
|
||||
}
|
||||
|
||||
if (!ParentIndexNumber.HasValue)
|
||||
{
|
||||
var season = Season;
|
||||
if (season != null)
|
||||
{
|
||||
if (season.ParentIndexNumber.HasValue)
|
||||
{
|
||||
ParentIndexNumber = season.ParentIndexNumber;
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,272 +0,0 @@
|
||||
using System;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Users;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities.TV
|
||||
{
|
||||
/// <summary>
|
||||
/// Class Season
|
||||
/// </summary>
|
||||
public class Season : Folder, IHasSeries, IHasLookupInfo<SeasonInfo>
|
||||
{
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsAddingToPlaylist
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool IsPreSorted
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsDateLastMediaAdded
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsPeople
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override bool SupportsInheritedParentImages
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override Guid? DisplayParentId
|
||||
{
|
||||
get { return SeriesId; }
|
||||
}
|
||||
|
||||
public override double? GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
double value = 2;
|
||||
value /= 3;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public string FindSeriesSortName()
|
||||
{
|
||||
var series = Series;
|
||||
return series == null ? SeriesName : series.SortName;
|
||||
}
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
{
|
||||
var list = base.GetUserDataKeys();
|
||||
|
||||
var series = Series;
|
||||
if (series != null)
|
||||
{
|
||||
list.InsertRange(0, series.GetUserDataKeys().Select(i => i + (IndexNumber ?? 0).ToString("000")));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public override int GetChildCount(User user)
|
||||
{
|
||||
var result = GetChildren(user, true).Count;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This Episode's Series Instance
|
||||
/// </summary>
|
||||
/// <value>The series.</value>
|
||||
[IgnoreDataMember]
|
||||
public Series Series
|
||||
{
|
||||
get
|
||||
{
|
||||
var seriesId = SeriesId ?? FindSeriesId();
|
||||
return seriesId.HasValue ? (LibraryManager.GetItemById(seriesId.Value) as Series) : null;
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string SeriesPath
|
||||
{
|
||||
get
|
||||
{
|
||||
var series = Series;
|
||||
|
||||
if (series != null)
|
||||
{
|
||||
return series.Path;
|
||||
}
|
||||
|
||||
return FileSystem.GetDirectoryName(Path);
|
||||
}
|
||||
}
|
||||
|
||||
public override string CreatePresentationUniqueKey()
|
||||
{
|
||||
if (IndexNumber.HasValue)
|
||||
{
|
||||
var series = Series;
|
||||
if (series != null)
|
||||
{
|
||||
return series.PresentationUniqueKey + "-" + (IndexNumber ?? 0).ToString("000");
|
||||
}
|
||||
}
|
||||
|
||||
return base.CreatePresentationUniqueKey();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the name of the sort.
|
||||
/// </summary>
|
||||
/// <returns>System.String.</returns>
|
||||
protected override string CreateSortName()
|
||||
{
|
||||
return IndexNumber != null ? IndexNumber.Value.ToString("0000") : Name;
|
||||
}
|
||||
|
||||
protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query)
|
||||
{
|
||||
if (query.User == null)
|
||||
{
|
||||
return base.GetItemsInternal(query);
|
||||
}
|
||||
|
||||
var user = query.User;
|
||||
|
||||
Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
|
||||
|
||||
var items = GetEpisodes(user, query.DtoOptions).Where(filter);
|
||||
|
||||
var result = PostFilterAndSort(items, query, false, false);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the episodes.
|
||||
/// </summary>
|
||||
public List<BaseItem> GetEpisodes(User user, DtoOptions options)
|
||||
{
|
||||
return GetEpisodes(Series, user, options);
|
||||
}
|
||||
|
||||
public List<BaseItem> GetEpisodes(Series series, User user, DtoOptions options)
|
||||
{
|
||||
return GetEpisodes(series, user, null, options);
|
||||
}
|
||||
|
||||
public List<BaseItem> GetEpisodes(Series series, User user, IEnumerable<Episode> allSeriesEpisodes, DtoOptions options)
|
||||
{
|
||||
return series.GetSeasonEpisodes(this, user, allSeriesEpisodes, options);
|
||||
}
|
||||
|
||||
public List<BaseItem> GetEpisodes()
|
||||
{
|
||||
return Series.GetSeasonEpisodes(this, null, null, new DtoOptions(true));
|
||||
}
|
||||
|
||||
public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
|
||||
{
|
||||
return GetEpisodes(user, new DtoOptions(true));
|
||||
}
|
||||
|
||||
protected override bool GetBlockUnratedValue(UserPolicy config)
|
||||
{
|
||||
// Don't block. Let either the entire series rating or episode rating determine it
|
||||
return false;
|
||||
}
|
||||
|
||||
public override UnratedItem GetBlockUnratedType()
|
||||
{
|
||||
return UnratedItem.Series;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string SeriesPresentationUniqueKey { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public string SeriesName { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public Guid? SeriesId { get; set; }
|
||||
|
||||
public string FindSeriesPresentationUniqueKey()
|
||||
{
|
||||
var series = Series;
|
||||
return series == null ? null : series.PresentationUniqueKey;
|
||||
}
|
||||
|
||||
public string FindSeriesName()
|
||||
{
|
||||
var series = Series;
|
||||
return series == null ? SeriesName : series.Name;
|
||||
}
|
||||
|
||||
public Guid? FindSeriesId()
|
||||
{
|
||||
var series = FindParent<Series>();
|
||||
return series == null ? (Guid?)null : series.Id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the lookup information.
|
||||
/// </summary>
|
||||
/// <returns>SeasonInfo.</returns>
|
||||
public SeasonInfo GetLookupInfo()
|
||||
{
|
||||
var id = GetItemLookupInfo<SeasonInfo>();
|
||||
|
||||
var series = Series;
|
||||
|
||||
if (series != null)
|
||||
{
|
||||
id.SeriesProviderIds = series.ProviderIds;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
public override bool BeforeMetadataRefresh()
|
||||
{
|
||||
var hasChanges = base.BeforeMetadataRefresh();
|
||||
|
||||
if (!IndexNumber.HasValue && !string.IsNullOrEmpty(Path))
|
||||
{
|
||||
IndexNumber = IndexNumber ?? LibraryManager.GetSeasonNumberFromPath(Path);
|
||||
|
||||
// If a change was made record it
|
||||
if (IndexNumber.HasValue)
|
||||
{
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user