aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MediaBrowser.Api/ApiEntryPoint.cs18
-rw-r--r--MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs2
-rw-r--r--MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs2
-rw-r--r--MediaBrowser.Api/UserLibrary/UserLibraryService.cs4
-rw-r--r--MediaBrowser.Common/Extensions/BaseExtensions.cs23
-rw-r--r--MediaBrowser.Controller/Channels/ChannelVideoItem.cs12
-rw-r--r--MediaBrowser.Controller/Channels/IChannelManager.cs8
-rw-r--r--MediaBrowser.Controller/Channels/IChannelMediaItem.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Audio/Audio.cs1
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs121
-rw-r--r--MediaBrowser.Controller/Entities/Extensions.cs9
-rw-r--r--MediaBrowser.Controller/Entities/Movies/Movie.cs28
-rw-r--r--MediaBrowser.Controller/Entities/Video.cs1
-rw-r--r--MediaBrowser.Controller/Library/IIntroProvider.cs9
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs2
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj1
-rw-r--r--MediaBrowser.Controller/Providers/IExtrasProvider.cs39
-rw-r--r--MediaBrowser.Controller/Providers/ItemLookupInfo.cs6
-rw-r--r--MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs9
-rw-r--r--MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj3
-rw-r--r--MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj3
-rw-r--r--MediaBrowser.Model/Configuration/CinemaModeConfiguration.cs23
-rw-r--r--MediaBrowser.Model/Configuration/ServerConfiguration.cs5
-rw-r--r--MediaBrowser.Model/Configuration/UserConfiguration.cs1
-rw-r--r--MediaBrowser.Model/Entities/ExtraType.cs16
-rw-r--r--MediaBrowser.Model/Entities/MediaUrl.cs1
-rw-r--r--MediaBrowser.Model/MediaBrowser.Model.csproj2
-rw-r--r--MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs10
-rw-r--r--MediaBrowser.Providers/Channels/VideoChannelItemMetadataService.cs6
-rw-r--r--MediaBrowser.Providers/Manager/MetadataService.cs15
-rw-r--r--MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs3
-rw-r--r--MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs1
-rw-r--r--MediaBrowser.Providers/Movies/MovieDbImageProvider.cs9
-rw-r--r--MediaBrowser.Providers/Movies/MovieDbProvider.cs8
-rw-r--r--MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs24
-rw-r--r--MediaBrowser.Providers/Movies/MovieExternalIds.cs18
-rw-r--r--MediaBrowser.Providers/Omdb/OmdbItemProvider.cs19
-rw-r--r--MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Channels/ChannelManager.cs40
-rw-r--r--MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs136
-rw-r--r--MediaBrowser.Server.Implementations/Connect/ConnectManager.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs361
-rw-r--r--MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs3
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs35
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/LocalTrailerResolver.cs12
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json3
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/server.json46
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj2
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardService.cs6
-rw-r--r--MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj21
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec4
-rw-r--r--Nuget/MediaBrowser.Common.nuspec2
-rw-r--r--Nuget/MediaBrowser.Model.Signed.nuspec2
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec4
55 files changed, 1014 insertions, 141 deletions
diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs
index 7c67f0a73..435bca0b8 100644
--- a/MediaBrowser.Api/ApiEntryPoint.cs
+++ b/MediaBrowser.Api/ApiEntryPoint.cs
@@ -314,17 +314,16 @@ namespace MediaBrowser.Api
/// </summary>
/// <param name="deviceId">The device id.</param>
/// <param name="deleteFiles">The delete files.</param>
- /// <param name="acquireLock">if set to <c>true</c> [acquire lock].</param>
/// <returns>Task.</returns>
/// <exception cref="ArgumentNullException">deviceId</exception>
- internal Task KillTranscodingJobs(string deviceId, Func<string, bool> deleteFiles, bool acquireLock)
+ internal Task KillTranscodingJobs(string deviceId, Func<string, bool> deleteFiles)
{
if (string.IsNullOrEmpty(deviceId))
{
throw new ArgumentNullException("deviceId");
}
- return KillTranscodingJobs(j => string.Equals(deviceId, j.DeviceId, StringComparison.OrdinalIgnoreCase), deleteFiles, acquireLock);
+ return KillTranscodingJobs(j => string.Equals(deviceId, j.DeviceId, StringComparison.OrdinalIgnoreCase), deleteFiles);
}
/// <summary>
@@ -332,9 +331,8 @@ namespace MediaBrowser.Api
/// </summary>
/// <param name="killJob">The kill job.</param>
/// <param name="deleteFiles">The delete files.</param>
- /// <param name="acquireLock">if set to <c>true</c> [acquire lock].</param>
/// <returns>Task.</returns>
- internal async Task KillTranscodingJobs(Func<TranscodingJob, bool> killJob, Func<string, bool> deleteFiles, bool acquireLock)
+ internal async Task KillTranscodingJobs(Func<TranscodingJob, bool> killJob, Func<string, bool> deleteFiles)
{
var jobs = new List<TranscodingJob>();
@@ -350,10 +348,7 @@ namespace MediaBrowser.Api
return;
}
- if (acquireLock)
- {
- await TranscodingStartLock.WaitAsync(CancellationToken.None).ConfigureAwait(false);
- }
+ await TranscodingStartLock.WaitAsync(CancellationToken.None).ConfigureAwait(false);
try
{
@@ -364,10 +359,7 @@ namespace MediaBrowser.Api
}
finally
{
- if (acquireLock)
- {
- TranscodingStartLock.Release();
- }
+ TranscodingStartLock.Release();
}
}
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index 2bb706769..fb8168198 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -139,7 +139,7 @@ namespace MediaBrowser.Api.Playback.Hls
// If the playlist doesn't already exist, startup ffmpeg
try
{
- await ApiEntryPoint.Instance.KillTranscodingJobs(j => j.Type == TranscodingJobType.Hls && string.Equals(j.DeviceId, request.DeviceId, StringComparison.OrdinalIgnoreCase), p => !string.Equals(p, playlistPath, StringComparison.OrdinalIgnoreCase), false).ConfigureAwait(false);
+ await ApiEntryPoint.Instance.KillTranscodingJobs(j => j.Type == TranscodingJobType.Hls && string.Equals(j.DeviceId, request.DeviceId, StringComparison.OrdinalIgnoreCase), p => !string.Equals(p, playlistPath, StringComparison.OrdinalIgnoreCase)).ConfigureAwait(false);
if (currentTranscodingIndex.HasValue)
{
diff --git a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
index 7e32246a2..a8d4c6b86 100644
--- a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
+++ b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
@@ -72,7 +72,7 @@ namespace MediaBrowser.Api.Playback.Hls
public void Delete(StopEncodingProcess request)
{
- var task = ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, path => true, true);
+ var task = ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, path => true);
Task.WaitAll(task);
}
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index b156b68d1..ff86c8473 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -566,13 +566,13 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
- public object Get(GetIntros request)
+ public async Task<object> Get(GetIntros request)
{
var user = _userManager.GetUserById(request.UserId);
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id);
- var items = _libraryManager.GetIntros(item, user);
+ var items = await _libraryManager.GetIntros(item, user).ConfigureAwait(false);
// Get everything
var fields = Enum.GetNames(typeof(ItemFields))
diff --git a/MediaBrowser.Common/Extensions/BaseExtensions.cs b/MediaBrowser.Common/Extensions/BaseExtensions.cs
index 452c47159..be2fbffc6 100644
--- a/MediaBrowser.Common/Extensions/BaseExtensions.cs
+++ b/MediaBrowser.Common/Extensions/BaseExtensions.cs
@@ -1,4 +1,5 @@
using System;
+using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
@@ -55,6 +56,28 @@ namespace MediaBrowser.Common.Extensions
}
/// <summary>
+ /// Removes the accent.
+ /// </summary>
+ /// <param name="text">The text.</param>
+ /// <returns>System.String.</returns>
+ public static string RemoveAccent(this string text)
+ {
+ var normalizedString = text.Normalize(NormalizationForm.FormD);
+ var stringBuilder = new StringBuilder();
+
+ foreach (var c in normalizedString)
+ {
+ var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
+ if (unicodeCategory != UnicodeCategory.NonSpacingMark)
+ {
+ stringBuilder.Append(c);
+ }
+ }
+
+ return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
+ }
+
+ /// <summary>
/// Gets the M d5.
/// </summary>
/// <param name="str">The STR.</param>
diff --git a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs
index 10e486e71..5d133c983 100644
--- a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs
+++ b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto;
@@ -9,7 +10,7 @@ using System.Linq;
namespace MediaBrowser.Controller.Channels
{
- public class ChannelVideoItem : Video, IChannelMediaItem
+ public class ChannelVideoItem : Video, IChannelMediaItem, IHasLookupInfo<ChannelItemLookupInfo>
{
public string ExternalId { get; set; }
@@ -87,5 +88,14 @@ namespace MediaBrowser.Controller.Channels
return list;
}
+
+ public ChannelItemLookupInfo GetLookupInfo()
+ {
+ var info = GetItemLookupInfo<ChannelItemLookupInfo>();
+
+ info.ContentType = ContentType;
+
+ return info;
+ }
}
}
diff --git a/MediaBrowser.Controller/Channels/IChannelManager.cs b/MediaBrowser.Controller/Channels/IChannelManager.cs
index 252e2aee5..07fb89132 100644
--- a/MediaBrowser.Controller/Channels/IChannelManager.cs
+++ b/MediaBrowser.Controller/Channels/IChannelManager.cs
@@ -60,6 +60,14 @@ namespace MediaBrowser.Controller.Channels
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&lt;QueryResult&lt;BaseItem&gt;&gt;.</returns>
+ Task<QueryResult<BaseItem>> GetAllMediaInternal(AllChannelMediaQuery query, CancellationToken cancellationToken);
+
+ /// <summary>
/// Gets all media.
/// </summary>
/// <param name="query">The query.</param>
diff --git a/MediaBrowser.Controller/Channels/IChannelMediaItem.cs b/MediaBrowser.Controller/Channels/IChannelMediaItem.cs
index db8e2b292..e39d98e13 100644
--- a/MediaBrowser.Controller/Channels/IChannelMediaItem.cs
+++ b/MediaBrowser.Controller/Channels/IChannelMediaItem.cs
@@ -5,8 +5,6 @@ namespace MediaBrowser.Controller.Channels
{
public interface IChannelMediaItem : IChannelItem
{
- bool IsInfiniteStream { get; set; }
-
long? RunTimeTicks { get; set; }
string MediaType { get; }
diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs
index 25d41565a..447328ea1 100644
--- a/MediaBrowser.Controller/Entities/Audio/Audio.cs
+++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs
@@ -28,6 +28,7 @@ namespace MediaBrowser.Controller.Entities.Audio
public string Container { get; set; }
public int? TotalBitrate { get; set; }
public List<string> Tags { get; set; }
+ public ExtraType ExtraType { get; set; }
public bool IsThemeMedia { get; set; }
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 3830fa1c1..e75f17f9a 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -41,16 +41,25 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// The supported image extensions
/// </summary>
- public static readonly string[] SupportedImageExtensions = new[] { ".png", ".jpg", ".jpeg", ".tbn" };
+ public static readonly string[] SupportedImageExtensions = { ".png", ".jpg", ".jpeg", ".tbn" };
/// <summary>
/// The trailer folder name
/// </summary>
- public const string TrailerFolderName = "trailers";
- public const string ThemeSongsFolderName = "theme-music";
- public const string ThemeSongFilename = "theme";
- public const string ThemeVideosFolderName = "backdrops";
- public const string XbmcTrailerFileSuffix = "-trailer";
+ public static string TrailerFolderName = "trailers";
+ public static string ThemeSongsFolderName = "theme-music";
+ public static string ThemeSongFilename = "theme";
+ public static string ThemeVideosFolderName = "backdrops";
+
+ public static List<KeyValuePair<string, ExtraType>> ExtraSuffixes = new List<KeyValuePair<string, ExtraType>>
+ {
+ new KeyValuePair<string,ExtraType>("-trailer", ExtraType.Trailer),
+ new KeyValuePair<string,ExtraType>("-deleted", ExtraType.DeletedScene),
+ new KeyValuePair<string,ExtraType>("-behindthescenes", ExtraType.BehindTheScenes),
+ new KeyValuePair<string,ExtraType>("-interview", ExtraType.Interview),
+ new KeyValuePair<string,ExtraType>("-scene", ExtraType.Scene),
+ new KeyValuePair<string,ExtraType>("-sample", ExtraType.Sample)
+ };
public List<ItemImageInfo> ImageInfos { get; set; }
@@ -167,7 +176,7 @@ namespace MediaBrowser.Controller.Entities
{
// Local trailer, special feature, theme video, etc.
// An item that belongs to another item but is not part of the Parent-Child tree
- return !IsFolder && Parent == null;
+ return !IsFolder && Parent == null && LocationType == LocationType.FileSystem;
}
}
@@ -552,11 +561,24 @@ namespace MediaBrowser.Controller.Entities
.Where(i => string.Equals(i.Name, TrailerFolderName, StringComparison.OrdinalIgnoreCase))
.SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
.ToList();
-
- // Support plex/xbmc convention
+
+ var extraTypes = new List<ExtraType> { ExtraType.Trailer };
+ var suffixes = ExtraSuffixes.Where(i => extraTypes.Contains(i.Value))
+ .Select(i => i.Key)
+ .ToList();
+
files.AddRange(fileSystemChildren.OfType<FileInfo>()
- .Where(i => FileSystem.GetFileNameWithoutExtension(i).EndsWith(XbmcTrailerFileSuffix, StringComparison.OrdinalIgnoreCase) && !string.Equals(Path, i.FullName, StringComparison.OrdinalIgnoreCase))
- );
+ .Where(i =>
+ {
+ var nameEithoutExtension = FileSystem.GetFileNameWithoutExtension(i);
+
+ if (!suffixes.Any(s => nameEithoutExtension.EndsWith(s, StringComparison.OrdinalIgnoreCase)))
+ {
+ return false;
+ }
+
+ return !string.Equals(Path, i.FullName, StringComparison.OrdinalIgnoreCase);
+ }));
return LibraryManager.ResolvePaths<Trailer>(files, directoryService, null).Select(video =>
{
@@ -568,12 +590,79 @@ namespace MediaBrowser.Controller.Entities
video = dbItem;
}
+ if (video != null)
+ {
+ video.ExtraType = ExtraType.Trailer;
+ }
+
+ return video;
+
+ // Sort them so that the list can be easily compared for changes
+ }).OrderBy(i => i.Path).ToList();
+ }
+
+ protected IEnumerable<Video> LoadSpecialFeatures(List<FileSystemInfo> fileSystemChildren, IDirectoryService directoryService)
+ {
+ var files = fileSystemChildren.OfType<DirectoryInfo>()
+ .Where(i => string.Equals(i.Name, "extras", StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, "specials", StringComparison.OrdinalIgnoreCase))
+ .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
+ .ToList();
+
+ var extraTypes = new List<ExtraType> { ExtraType.BehindTheScenes, ExtraType.DeletedScene, ExtraType.Interview, ExtraType.Sample, ExtraType.Scene, ExtraType.Clip };
+ var suffixes = ExtraSuffixes.Where(i => extraTypes.Contains(i.Value))
+ .Select(i => i.Key)
+ .ToList();
+
+ files.AddRange(fileSystemChildren.OfType<FileInfo>()
+ .Where(i =>
+ {
+ var nameEithoutExtension = FileSystem.GetFileNameWithoutExtension(i);
+
+ if (!suffixes.Any(s => nameEithoutExtension.EndsWith(s, StringComparison.OrdinalIgnoreCase)))
+ {
+ return false;
+ }
+
+ return !string.Equals(Path, i.FullName, StringComparison.OrdinalIgnoreCase);
+ }));
+
+ return LibraryManager.ResolvePaths<Video>(files, directoryService, null).Select(video =>
+ {
+ // Try to retrieve it from the db. If we don't find it, use the resolved version
+ var dbItem = LibraryManager.GetItemById(video.Id) as Video;
+
+ if (dbItem != null)
+ {
+ video = dbItem;
+ }
+
+ if (video != null)
+ {
+ SetExtraTypeFromFilename(video);
+ }
+
return video;
// Sort them so that the list can be easily compared for changes
}).OrderBy(i => i.Path).ToList();
}
+ private void SetExtraTypeFromFilename(Video item)
+ {
+ var name = System.IO.Path.GetFileNameWithoutExtension(item.Path) ?? string.Empty;
+
+ foreach (var suffix in ExtraSuffixes)
+ {
+ if (name.EndsWith(suffix.Key, StringComparison.OrdinalIgnoreCase))
+ {
+ item.ExtraType = suffix.Value;
+ return;
+ }
+ }
+
+ item.ExtraType = ExtraType.Clip;
+ }
+
/// <summary>
/// Loads the theme songs.
/// </summary>
@@ -600,6 +689,11 @@ namespace MediaBrowser.Controller.Entities
audio = dbItem;
}
+ if (audio != null)
+ {
+ audio.ExtraType = ExtraType.ThemeSong;
+ }
+
return audio;
// Sort them so that the list can be easily compared for changes
@@ -626,6 +720,11 @@ namespace MediaBrowser.Controller.Entities
item = dbItem;
}
+ if (item != null)
+ {
+ item.ExtraType = ExtraType.ThemeVideo;
+ }
+
return item;
// Sort them so that the list can be easily compared for changes
diff --git a/MediaBrowser.Controller/Entities/Extensions.cs b/MediaBrowser.Controller/Entities/Extensions.cs
index 2a64bd3a4..5e792a03a 100644
--- a/MediaBrowser.Controller/Entities/Extensions.cs
+++ b/MediaBrowser.Controller/Entities/Extensions.cs
@@ -25,16 +25,11 @@ namespace MediaBrowser.Controller.Entities
var current = item.RemoteTrailers.FirstOrDefault(i => string.Equals(i.Url, url, StringComparison.OrdinalIgnoreCase));
- if (current != null)
- {
- current.IsDirectLink = isDirectLink;
- }
- else
+ if (current == null)
{
item.RemoteTrailers.Add(new MediaUrl
{
- Url = url,
- IsDirectLink = isDirectLink
+ Url = url
});
}
}
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index 837f3b9cf..8d2f19d4c 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -125,7 +125,7 @@ namespace MediaBrowser.Controller.Entities.Movies
return hasChanges;
}
- private async Task<bool> RefreshSpecialFeatures(MetadataRefreshOptions options, IEnumerable<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
+ private async Task<bool> RefreshSpecialFeatures(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
{
var newItems = LoadSpecialFeatures(fileSystemChildren, options.DirectoryService).ToList();
var newItemIds = newItems.Select(i => i.Id).ToList();
@@ -141,32 +141,6 @@ namespace MediaBrowser.Controller.Entities.Movies
return itemsChanged;
}
- /// <summary>
- /// Loads the special features.
- /// </summary>
- /// <returns>IEnumerable{Video}.</returns>
- private IEnumerable<Video> LoadSpecialFeatures(IEnumerable<FileSystemInfo> fileSystemChildren, IDirectoryService directoryService)
- {
- var files = fileSystemChildren.OfType<DirectoryInfo>()
- .Where(i => string.Equals(i.Name, "extras", StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, "specials", StringComparison.OrdinalIgnoreCase))
- .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly));
-
- return LibraryManager.ResolvePaths<Video>(files, directoryService, null).Select(video =>
- {
- // Try to retrieve it from the db. If we don't find it, use the resolved version
- var dbItem = LibraryManager.GetItemById(video.Id) as Video;
-
- if (dbItem != null)
- {
- video = dbItem;
- }
-
- return video;
-
- // Sort them so that the list can be easily compared for changes
- }).OrderBy(i => i.Path).ToList();
- }
-
protected override bool GetBlockUnratedValue(UserConfiguration config)
{
return config.BlockUnratedItems.Contains(UnratedItem.Movie);
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index 492a4a02f..59649de7f 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -41,6 +41,7 @@ namespace MediaBrowser.Controller.Entities
public string Container { get; set; }
public int? TotalBitrate { get; set; }
public string ShortOverview { get; set; }
+ public ExtraType ExtraType { get; set; }
/// <summary>
/// Gets or sets the timestamp.
diff --git a/MediaBrowser.Controller/Library/IIntroProvider.cs b/MediaBrowser.Controller/Library/IIntroProvider.cs
index a83d3c5eb..611aab387 100644
--- a/MediaBrowser.Controller/Library/IIntroProvider.cs
+++ b/MediaBrowser.Controller/Library/IIntroProvider.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Controller.Entities;
using System.Collections.Generic;
+using System.Threading.Tasks;
namespace MediaBrowser.Controller.Library
{
@@ -14,12 +15,18 @@ namespace MediaBrowser.Controller.Library
/// <param name="item">The item.</param>
/// <param name="user">The user.</param>
/// <returns>IEnumerable{System.String}.</returns>
- IEnumerable<IntroInfo> GetIntros(BaseItem item, User user);
+ Task<IEnumerable<IntroInfo>> GetIntros(BaseItem item, User user);
/// <summary>
/// Gets all intro files.
/// </summary>
/// <returns>IEnumerable{System.String}.</returns>
IEnumerable<string> GetAllIntroFiles();
+
+ /// <summary>
+ /// Gets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ string Name { get; }
}
}
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 8aaa08fdd..951513962 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -157,7 +157,7 @@ namespace MediaBrowser.Controller.Library
/// <param name="item">The item.</param>
/// <param name="user">The user.</param>
/// <returns>IEnumerable{System.String}.</returns>
- IEnumerable<Video> GetIntros(BaseItem item, User user);
+ Task<IEnumerable<Video>> GetIntros(BaseItem item, User user);
/// <summary>
/// Gets all intro files.
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 517200bb7..ce9e83009 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -234,6 +234,7 @@
<Compile Include="Providers\DirectoryService.cs" />
<Compile Include="Providers\ICustomMetadataProvider.cs" />
<Compile Include="Providers\IExternalId.cs" />
+ <Compile Include="Providers\IExtrasProvider.cs" />
<Compile Include="Providers\IForcedProvider.cs" />
<Compile Include="Providers\IHasChangeMonitor.cs" />
<Compile Include="Entities\IHasMetadata.cs" />
diff --git a/MediaBrowser.Controller/Providers/IExtrasProvider.cs b/MediaBrowser.Controller/Providers/IExtrasProvider.cs
new file mode 100644
index 000000000..953bf02a1
--- /dev/null
+++ b/MediaBrowser.Controller/Providers/IExtrasProvider.cs
@@ -0,0 +1,39 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Entities;
+
+namespace MediaBrowser.Controller.Providers
+{
+ public interface IExtrasProvider
+ {
+ /// <summary>
+ /// Gets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ string Name { get; }
+
+ /// <summary>
+ /// Supportses the specified item.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
+ bool Supports(IHasMetadata item);
+ }
+
+ public enum ExtraSource
+ {
+ Local = 1,
+ Metadata = 2,
+ Remote = 3
+ }
+
+ public class ExtraInfo
+ {
+ public string Path { get; set; }
+
+ public LocationType LocationType { get; set; }
+
+ public bool IsDownloadable { get; set; }
+
+ public ExtraType ExtraType { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs
index 7e6c6e140..56f285e4d 100644
--- a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs
+++ b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs
@@ -1,6 +1,7 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
@@ -236,4 +237,9 @@ namespace MediaBrowser.Controller.Providers
public int SeasonIndex { get; set; }
}
+
+ public class ChannelItemLookupInfo : ItemLookupInfo
+ {
+ public ChannelMediaContentType ContentType { get; set; }
+ }
}
diff --git a/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs b/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs
index 9f5eade8e..4ddfa5979 100644
--- a/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs
+++ b/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs
@@ -158,9 +158,10 @@ namespace MediaBrowser.Controller.Resolvers
// Normalize
// Remove whitespace
filename = filename.Replace("-", string.Empty);
+ filename = filename.Replace(".", string.Empty);
filename = Regex.Replace(filename, @"\s+", "");
- var prefixes = new[] { "disc", "cd", "disk" };
+ var prefixes = new[] { "disc", "cd", "disk", "vol", "volume" };
foreach (var prefix in prefixes)
{
@@ -210,7 +211,7 @@ namespace MediaBrowser.Controller.Resolvers
{
if (includeCreationTime)
{
- item.DateCreated = fileSystem.GetCreationTimeUtc(childData);
+ item.DateCreated = DateTime.UtcNow;
}
item.DateModified = fileSystem.GetLastWriteTimeUtc(childData);
@@ -223,7 +224,7 @@ namespace MediaBrowser.Controller.Resolvers
{
if (includeCreationTime)
{
- item.DateCreated = fileSystem.GetCreationTimeUtc(fileData);
+ item.DateCreated = DateTime.UtcNow;
}
item.DateModified = fileSystem.GetLastWriteTimeUtc(fileData);
}
@@ -233,7 +234,7 @@ namespace MediaBrowser.Controller.Resolvers
{
if (includeCreationTime)
{
- item.DateCreated = fileSystem.GetCreationTimeUtc(args.FileInfo);
+ item.DateCreated = DateTime.UtcNow;
}
item.DateModified = fileSystem.GetLastWriteTimeUtc(args.FileInfo);
}
diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
index 32054beb3..89a17055e 100644
--- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
+++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
@@ -374,6 +374,9 @@
<Compile Include="..\MediaBrowser.Model\Entities\EmptyRequestResult.cs">
<Link>Entities\EmptyRequestResult.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Entities\ExtraType.cs">
+ <Link>Entities\ExtraType.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\Entities\IHasProviderIds.cs">
<Link>Entities\IHasProviderIds.cs</Link>
</Compile>
diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
index e9153117b..acd463f59 100644
--- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
+++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
@@ -334,6 +334,9 @@
<Compile Include="..\MediaBrowser.Model\Entities\EmptyRequestResult.cs">
<Link>Entities\EmptyRequestResult.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Entities\ExtraType.cs">
+ <Link>Entities\ExtraType.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\Entities\IHasProviderIds.cs">
<Link>Entities\IHasProviderIds.cs</Link>
</Compile>
diff --git a/MediaBrowser.Model/Configuration/CinemaModeConfiguration.cs b/MediaBrowser.Model/Configuration/CinemaModeConfiguration.cs
new file mode 100644
index 000000000..35053e3de
--- /dev/null
+++ b/MediaBrowser.Model/Configuration/CinemaModeConfiguration.cs
@@ -0,0 +1,23 @@
+
+namespace MediaBrowser.Model.Configuration
+{
+ public class CinemaModeConfiguration
+ {
+ public bool EnableIntrosForMovies { get; set; }
+ public bool EnableIntrosForEpisodes { get; set; }
+ public bool EnableIntrosForWatchedContent { get; set; }
+ public bool EnableIntrosFromUpcomingTrailers { get; set; }
+ public bool EnableIntrosFromMoviesInLibrary { get; set; }
+ public bool EnableCustomIntro { get; set; }
+ public bool EnableIntrosParentalControl { get; set; }
+
+ public CinemaModeConfiguration()
+ {
+ EnableIntrosForMovies = true;
+ EnableCustomIntro = true;
+ EnableIntrosFromMoviesInLibrary = true;
+ EnableIntrosFromUpcomingTrailers = true;
+ EnableIntrosParentalControl = true;
+ }
+ }
+}
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index 4786194e2..9d125779b 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -179,6 +179,8 @@ namespace MediaBrowser.Model.Configuration
public bool SaveMetadataHidden { get; set; }
+ public bool FindInternetTrailers { get; set; }
+
/// <summary>
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
/// </summary>
@@ -204,7 +206,8 @@ namespace MediaBrowser.Model.Configuration
RealtimeMonitorDelay = 30;
- EnableInternetProviders = true;
+ EnableInternetProviders = true;
+ FindInternetTrailers = true;
PathSubstitutions = new PathSubstitution[] { };
diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs
index 3f25ba656..e535d7805 100644
--- a/MediaBrowser.Model/Configuration/UserConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs
@@ -82,6 +82,7 @@ namespace MediaBrowser.Model.Configuration
public bool SyncConnectName { get; set; }
public bool SyncConnectImage { get; set; }
+
/// <summary>
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
/// </summary>
diff --git a/MediaBrowser.Model/Entities/ExtraType.cs b/MediaBrowser.Model/Entities/ExtraType.cs
new file mode 100644
index 000000000..ab8da58c0
--- /dev/null
+++ b/MediaBrowser.Model/Entities/ExtraType.cs
@@ -0,0 +1,16 @@
+
+namespace MediaBrowser.Model.Entities
+{
+ public enum ExtraType
+ {
+ Clip = 1,
+ Trailer = 2,
+ BehindTheScenes = 3,
+ DeletedScene = 4,
+ Interview = 5,
+ Scene = 6,
+ Sample = 7,
+ ThemeSong = 8,
+ ThemeVideo = 9
+ }
+}
diff --git a/MediaBrowser.Model/Entities/MediaUrl.cs b/MediaBrowser.Model/Entities/MediaUrl.cs
index 9aa7207ed..24e3b1492 100644
--- a/MediaBrowser.Model/Entities/MediaUrl.cs
+++ b/MediaBrowser.Model/Entities/MediaUrl.cs
@@ -6,6 +6,5 @@ namespace MediaBrowser.Model.Entities
public string Url { get; set; }
public string Name { get; set; }
public VideoSize? VideoSize { get; set; }
- public bool IsDirectLink { get; set; }
}
}
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index c4da280e2..105504121 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -79,11 +79,13 @@
<Compile Include="Collections\CollectionCreationResult.cs" />
<Compile Include="Configuration\ChannelOptions.cs" />
<Compile Include="Configuration\ChapterOptions.cs" />
+ <Compile Include="Configuration\CinemaModeConfiguration.cs" />
<Compile Include="Configuration\XbmcMetadataOptions.cs" />
<Compile Include="Configuration\SubtitlePlaybackMode.cs" />
<Compile Include="Connect\UserLinkType.cs" />
<Compile Include="Drawing\ImageOrientation.cs" />
<Compile Include="Dto\StreamOptions.cs" />
+ <Compile Include="Entities\ExtraType.cs" />
<Compile Include="FileOrganization\AutoOrganizeOptions.cs" />
<Compile Include="FileOrganization\TvFileOrganizationOptions.cs" />
<Compile Include="Configuration\BaseApplicationConfiguration.cs" />
diff --git a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs
index e17a96a43..266202b96 100644
--- a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs
+++ b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs
@@ -50,10 +50,6 @@ namespace MediaBrowser.Providers.BoxSets
{
var tmdbId = searchInfo.GetProviderId(MetadataProviders.Tmdb);
- var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false);
-
- var tmdbImageUrl = tmdbSettings.images.base_url + "original";
-
if (!string.IsNullOrEmpty(tmdbId))
{
await EnsureInfo(tmdbId, searchInfo.MetadataLanguage, cancellationToken).ConfigureAwait(false);
@@ -62,7 +58,11 @@ namespace MediaBrowser.Providers.BoxSets
var info = _json.DeserializeFromFile<RootObject>(dataFilePath);
var images = (info.images ?? new Images()).posters ?? new List<Poster>();
-
+
+ var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false);
+
+ var tmdbImageUrl = tmdbSettings.images.base_url + "original";
+
var result = new RemoteSearchResult
{
Name = info.name,
diff --git a/MediaBrowser.Providers/Channels/VideoChannelItemMetadataService.cs b/MediaBrowser.Providers/Channels/VideoChannelItemMetadataService.cs
index ddd112207..0b3f5a814 100644
--- a/MediaBrowser.Providers/Channels/VideoChannelItemMetadataService.cs
+++ b/MediaBrowser.Providers/Channels/VideoChannelItemMetadataService.cs
@@ -1,15 +1,15 @@
-using System.Collections.Generic;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
+using System.Collections.Generic;
namespace MediaBrowser.Providers.Channels
{
- public class VideoChannelItemMetadataService : MetadataService<ChannelVideoItem, ItemLookupInfo>
+ public class VideoChannelItemMetadataService : MetadataService<ChannelVideoItem, ChannelItemLookupInfo>
{
public VideoChannelItemMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index 46ba62873..8657d568f 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -489,6 +489,8 @@ namespace MediaBrowser.Providers.Manager
if (result.HasMetadata)
{
+ NormalizeRemoteResult(result.Item);
+
MergeData(result.Item, temp, new List<MetadataFields>(), false, false);
refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataDownload;
@@ -522,6 +524,19 @@ namespace MediaBrowser.Providers.Manager
return refreshResult;
}
+ private void NormalizeRemoteResult(TItemType item)
+ {
+ if (!ServerConfigurationManager.Configuration.FindInternetTrailers)
+ {
+ var hasTrailers = item as IHasTrailers;
+
+ if (hasTrailers != null)
+ {
+ hasTrailers.RemoteTrailers.Clear();
+ }
+ }
+ }
+
protected virtual void AfterRemoteRefresh(TItemType item)
{
diff --git a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
index f5b43e407..3f81ae6cd 100644
--- a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
+++ b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
@@ -1,11 +1,12 @@
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
index 34e535a85..601901d18 100644
--- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
+++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
@@ -251,7 +251,6 @@ namespace MediaBrowser.Providers.Movies
hasTrailers.RemoteTrailers = movieData.trailers.youtube.Select(i => new MediaUrl
{
Url = string.Format("http://www.youtube.com/watch?v={0}", i.source),
- IsDirectLink = false,
Name = i.name,
VideoSize = string.Equals("hd", i.size, StringComparison.OrdinalIgnoreCase) ? VideoSize.HighDefinition : VideoSize.StandardDefinition
diff --git a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
index 9828a20bc..afecf78f5 100644
--- a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
@@ -1,7 +1,9 @@
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
@@ -45,6 +47,13 @@ namespace MediaBrowser.Providers.Movies
return !trailer.IsLocalTrailer;
}
+ var channelItem = item as ChannelVideoItem;
+
+ if (channelItem != null && channelItem.ContentType == ChannelMediaContentType.Trailer)
+ {
+ return true;
+ }
+
// Don't support local trailers
return item is Movie || item is MusicVideo;
}
diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs
index 00a80af83..b43dd4540 100644
--- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs
@@ -56,10 +56,6 @@ namespace MediaBrowser.Providers.Movies
public async Task<IEnumerable<RemoteSearchResult>> GetMovieSearchResults(ItemLookupInfo searchInfo, CancellationToken cancellationToken)
{
- var tmdbSettings = await GetTmdbSettings(cancellationToken).ConfigureAwait(false);
-
- var tmdbImageUrl = tmdbSettings.images.base_url + "original";
-
var tmdbId = searchInfo.GetProviderId(MetadataProviders.Tmdb);
if (!string.IsNullOrEmpty(tmdbId))
@@ -72,6 +68,10 @@ namespace MediaBrowser.Providers.Movies
var obj = _jsonSerializer.DeserializeFromFile<CompleteMovieData>(dataFilePath);
+ var tmdbSettings = await GetTmdbSettings(cancellationToken).ConfigureAwait(false);
+
+ var tmdbImageUrl = tmdbSettings.images.base_url + "original";
+
var remoteResult = new RemoteSearchResult
{
Name = obj.title ?? obj.original_title ?? obj.name,
diff --git a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs
index 78ea3e99c..3676e6d61 100644
--- a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs
@@ -1,6 +1,8 @@
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Providers;
using System;
using System.Collections.Generic;
@@ -9,7 +11,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Movies
{
- public class MovieDbTrailerProvider : IRemoteMetadataProvider<Trailer, TrailerInfo>, IHasOrder
+ public class MovieDbTrailerProvider : IRemoteMetadataProvider<Trailer, TrailerInfo>, IHasOrder, IRemoteMetadataProvider<ChannelVideoItem, ChannelItemLookupInfo>
{
private readonly IHttpClient _httpClient;
@@ -28,6 +30,26 @@ namespace MediaBrowser.Providers.Movies
return MovieDbProvider.Current.GetMovieSearchResults(searchInfo, cancellationToken);
}
+ public Task<MetadataResult<ChannelVideoItem>> GetMetadata(ChannelItemLookupInfo info, CancellationToken cancellationToken)
+ {
+ if (info.ContentType != Model.Channels.ChannelMediaContentType.Trailer)
+ {
+ return Task.FromResult(new MetadataResult<ChannelVideoItem>());
+ }
+
+ return MovieDbProvider.Current.GetItemMetadata<ChannelVideoItem>(info, cancellationToken);
+ }
+
+ public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(ChannelItemLookupInfo searchInfo, CancellationToken cancellationToken)
+ {
+ if (searchInfo.ContentType != ChannelMediaContentType.Trailer)
+ {
+ return Task.FromResult<IEnumerable<RemoteSearchResult>>(new List<RemoteSearchResult>());
+ }
+
+ return MovieDbProvider.Current.GetMovieSearchResults(searchInfo, cancellationToken);
+ }
+
public string Name
{
get { return MovieDbProvider.Current.Name; }
diff --git a/MediaBrowser.Providers/Movies/MovieExternalIds.cs b/MediaBrowser.Providers/Movies/MovieExternalIds.cs
index e7625d31c..6ed30cdc9 100644
--- a/MediaBrowser.Providers/Movies/MovieExternalIds.cs
+++ b/MediaBrowser.Providers/Movies/MovieExternalIds.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Providers.Movies
@@ -25,6 +27,13 @@ namespace MediaBrowser.Providers.Movies
public bool Supports(IHasProviderIds item)
{
+ var channelItem = item as ChannelVideoItem;
+
+ if (channelItem != null && channelItem.ContentType == ChannelMediaContentType.Trailer)
+ {
+ return true;
+ }
+
return item is Movie || item is Trailer || item is MusicVideo;
}
}
@@ -140,6 +149,13 @@ namespace MediaBrowser.Providers.Movies
public bool Supports(IHasProviderIds item)
{
+ var channelItem = item as ChannelVideoItem;
+
+ if (channelItem != null && channelItem.ContentType == ChannelMediaContentType.Trailer)
+ {
+ return true;
+ }
+
return item is Movie || item is Trailer || item is MusicVideo || item is Series || item is Episode;
}
}
diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs
index 08e9a3abf..4e8d7686c 100644
--- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs
+++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs
@@ -1,8 +1,10 @@
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Providers;
@@ -17,7 +19,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Omdb
{
public class OmdbItemProvider : IRemoteMetadataProvider<Series, SeriesInfo>,
- IRemoteMetadataProvider<Movie, MovieInfo>, IRemoteMetadataProvider<Trailer, TrailerInfo>
+ IRemoteMetadataProvider<Movie, MovieInfo>, IRemoteMetadataProvider<Trailer, TrailerInfo>, IRemoteMetadataProvider<ChannelVideoItem, ChannelItemLookupInfo>
{
private readonly IJsonSerializer _jsonSerializer;
private readonly IHttpClient _httpClient;
@@ -45,6 +47,21 @@ namespace MediaBrowser.Providers.Omdb
return new List<RemoteSearchResult>();
}
+ public Task<MetadataResult<ChannelVideoItem>> GetMetadata(ChannelItemLookupInfo info, CancellationToken cancellationToken)
+ {
+ if (info.ContentType != ChannelMediaContentType.Trailer)
+ {
+ return Task.FromResult(new MetadataResult<ChannelVideoItem>());
+ }
+
+ return GetMovieResult<ChannelVideoItem>(info, cancellationToken);
+ }
+
+ public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(ChannelItemLookupInfo searchInfo, CancellationToken cancellationToken)
+ {
+ return new List<RemoteSearchResult>();
+ }
+
public string Name
{
get { return "The Open Movie Database"; }
diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs b/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs
index 1d95dbc1b..8c510afd2 100644
--- a/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs
+++ b/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs
@@ -332,7 +332,7 @@ namespace MediaBrowser.Server.Implementations.Channels
{
return new ITaskTrigger[]
{
- new IntervalTrigger{ Interval = TimeSpan.FromHours(6)},
+ new IntervalTrigger{ Interval = TimeSpan.FromHours(3)},
};
}
diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
index dfd24a248..12aa670b3 100644
--- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
+++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
@@ -62,7 +62,7 @@ namespace MediaBrowser.Server.Implementations.Channels
{
get
{
- return TimeSpan.FromHours(12);
+ return TimeSpan.FromHours(6);
}
}
@@ -663,7 +663,7 @@ namespace MediaBrowser.Server.Implementations.Channels
private async Task<IEnumerable<ChannelItemInfo>> GetLatestItems(ISupportsLatestMedia indexable, IChannel channel, string userId, CancellationToken cancellationToken)
{
- var cacheLength = TimeSpan.FromHours(12);
+ var cacheLength = CacheLength;
var cachePath = GetChannelDataCachePath(channel, userId, "channelmanager-latest", null, false);
try
@@ -720,7 +720,7 @@ namespace MediaBrowser.Server.Implementations.Channels
}
}
- public async Task<QueryResult<BaseItemDto>> GetAllMedia(AllChannelMediaQuery query, CancellationToken cancellationToken)
+ public async Task<QueryResult<BaseItem>> GetAllMediaInternal(AllChannelMediaQuery query, CancellationToken cancellationToken)
{
var user = string.IsNullOrWhiteSpace(query.UserId)
? null
@@ -798,19 +798,43 @@ namespace MediaBrowser.Server.Implementations.Channels
var internalItems = await Task.WhenAll(itemTasks).ConfigureAwait(false);
await RefreshIfNeeded(internalItems, cancellationToken).ConfigureAwait(false);
- var returnItemArray = internalItems.Select(i => _dtoService.GetBaseItemDto(i, query.Fields, user))
- .ToArray();
+ var returnItemArray = internalItems.ToArray();
- return new QueryResult<BaseItemDto>
+ return new QueryResult<BaseItem>
{
TotalRecordCount = totalCount,
Items = returnItemArray
};
}
+
+ public async Task<QueryResult<BaseItemDto>> GetAllMedia(AllChannelMediaQuery query, CancellationToken cancellationToken)
+ {
+ var user = string.IsNullOrWhiteSpace(query.UserId)
+ ? null
+ : _userManager.GetUserById(query.UserId);
+
+ var internalResult = await GetAllMediaInternal(query, cancellationToken).ConfigureAwait(false);
+
+ // Get everything
+ var fields = Enum.GetNames(typeof(ItemFields))
+ .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
+ .ToList();
+
+ var returnItems = internalResult.Items.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
+ .ToArray();
+
+ var result = new QueryResult<BaseItemDto>
+ {
+ Items = returnItems,
+ TotalRecordCount = internalResult.TotalRecordCount
+ };
+
+ return result;
+ }
private async Task<ChannelItemResult> GetAllItems(IIndexableChannel indexable, IChannel channel, string userId, CancellationToken cancellationToken)
{
- var cacheLength = TimeSpan.FromHours(12);
+ var cacheLength = CacheLength;
var cachePath = GetChannelDataCachePath(channel, userId, "channelmanager-allitems", null, false);
try
@@ -1199,7 +1223,6 @@ namespace MediaBrowser.Server.Implementations.Channels
item.Genres = info.Genres;
item.Studios = info.Studios;
item.CommunityRating = info.CommunityRating;
- item.OfficialRating = info.OfficialRating;
item.Overview = info.Overview;
item.IndexNumber = info.IndexNumber;
item.ParentIndexNumber = info.ParentIndexNumber;
@@ -1207,6 +1230,7 @@ namespace MediaBrowser.Server.Implementations.Channels
item.PremiereDate = info.PremiereDate;
item.ProductionYear = info.ProductionYear;
item.ProviderIds = info.ProviderIds;
+ item.OfficialRating = info.OfficialRating;
item.DateCreated = info.DateCreated.HasValue ?
info.DateCreated.Value :
diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs b/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs
new file mode 100644
index 000000000..b067271c5
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs
@@ -0,0 +1,136 @@
+using System.Collections.Generic;
+using MediaBrowser.Common.Progress;
+using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Channels;
+using MediaBrowser.Model.Logging;
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Channels
+{
+ public class ChannelPostScanTask : ILibraryPostScanTask
+ {
+ private readonly IChannelManager _channelManager;
+ private readonly IUserManager _userManager;
+ private readonly ILogger _logger;
+
+ public ChannelPostScanTask(IChannelManager channelManager, IUserManager userManager, ILogger logger)
+ {
+ _channelManager = channelManager;
+ _userManager = userManager;
+ _logger = logger;
+ }
+
+ public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
+ {
+ var users = _userManager.Users
+ .Select(i => i.Id.ToString("N"))
+ .ToList();
+
+ var numComplete = 0;
+
+ foreach (var user in users)
+ {
+ double percentPerUser = 1;
+ percentPerUser /= users.Count;
+ var startingPercent = numComplete * percentPerUser * 100;
+
+ var innerProgress = new ActionableProgress<double>();
+ innerProgress.RegisterAction(p => progress.Report(startingPercent + (percentPerUser * p)));
+
+ await DownloadContent(user, cancellationToken, innerProgress).ConfigureAwait(false);
+
+ numComplete++;
+ double percent = numComplete;
+ percent /= users.Count;
+ progress.Report(percent * 100);
+ }
+
+ progress.Report(100);
+ }
+
+ private async Task DownloadContent(string user, CancellationToken cancellationToken, IProgress<double> progress)
+ {
+ var channels = await _channelManager.GetChannelsInternal(new ChannelQuery
+ {
+ UserId = user
+
+ }, cancellationToken);
+
+ var numComplete = 0;
+
+ foreach (var channel in channels.Items)
+ {
+ try
+ {
+ await GetAllItems(user, channel.Id.ToString("N"), null, false, cancellationToken).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error getting channel content", ex);
+ }
+
+ numComplete++;
+ double percent = numComplete;
+ percent /= channels.Items.Length;
+ progress.Report(percent * 100);
+ }
+
+ progress.Report(100);
+
+ }
+
+ private async Task GetAllItems(string user, string channelId, string folderId, bool recursive, CancellationToken cancellationToken)
+ {
+ var folderItems = new List<string>();
+
+ var result = await _channelManager.GetChannelItemsInternal(new ChannelItemQuery
+ {
+ ChannelId = channelId,
+ UserId = user,
+ FolderId = folderId
+
+ }, cancellationToken);
+
+ folderItems.AddRange(result.Items.Where(i => i.IsFolder).Select(i => i.Id.ToString("N")));
+
+ var totalRetrieved = result.Items.Length;
+ var totalCount = result.TotalRecordCount;
+
+ while (totalRetrieved < totalCount)
+ {
+ result = await _channelManager.GetChannelItemsInternal(new ChannelItemQuery
+ {
+ ChannelId = channelId,
+ UserId = user,
+ StartIndex = totalRetrieved,
+ FolderId = folderId
+
+ }, cancellationToken);
+
+ folderItems.AddRange(result.Items.Where(i => i.IsFolder).Select(i => i.Id.ToString("N")));
+
+ totalRetrieved += result.Items.Length;
+ totalCount = result.TotalRecordCount;
+ }
+
+ if (recursive)
+ {
+ foreach (var folder in folderItems)
+ {
+ try
+ {
+ await GetAllItems(user, channelId, folder, false, cancellationToken).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error getting channel content", ex);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
index 374d04f1d..a1b88a65f 100644
--- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
+++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
@@ -402,11 +402,11 @@ namespace MediaBrowser.Server.Implementations.Connect
}
else if (!string.IsNullOrWhiteSpace(query.Name))
{
- url = url + "?nameoremail=" + WebUtility.UrlEncode(query.Name);
+ url = url + "?name=" + WebUtility.UrlEncode(query.Name);
}
else if (!string.IsNullOrWhiteSpace(query.Email))
{
- url = url + "?nameoremail=" + WebUtility.UrlEncode(query.Email);
+ url = url + "?name=" + WebUtility.UrlEncode(query.Email);
}
var options = new HttpRequestOptions
diff --git a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs
new file mode 100644
index 000000000..b5e449eae
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs
@@ -0,0 +1,361 @@
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Security;
+using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Localization;
+using MediaBrowser.Model.Channels;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Entities;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Intros
+{
+ public class DefaultIntroProvider : IIntroProvider
+ {
+ private readonly ISecurityManager _security;
+ private readonly IChannelManager _channelManager;
+ private readonly ILocalizationManager _localization;
+ private readonly IConfigurationManager _serverConfig;
+
+ public DefaultIntroProvider(ISecurityManager security, IChannelManager channelManager, ILocalizationManager localization, IConfigurationManager serverConfig)
+ {
+ _security = security;
+ _channelManager = channelManager;
+ _localization = localization;
+ _serverConfig = serverConfig;
+ }
+
+ public async Task<IEnumerable<IntroInfo>> GetIntros(BaseItem item, User user)
+ {
+ var config = GetOptions();
+
+ if (item is Movie)
+ {
+ if (!config.EnableIntrosForMovies)
+ {
+ return new List<IntroInfo>();
+ }
+ }
+ else if (item is Episode)
+ {
+ if (!config.EnableIntrosForEpisodes)
+ {
+ return new List<IntroInfo>();
+ }
+ }
+ else
+ {
+ return new List<IntroInfo>();
+ }
+
+ if (!IsSupporter)
+ {
+ return new List<IntroInfo>();
+ }
+
+ var ratingLevel = string.IsNullOrWhiteSpace(item.OfficialRating)
+ ? (int?)null
+ : _localization.GetRatingLevel(item.OfficialRating);
+
+ var libaryItems = user.RootFolder.GetRecursiveChildren(user, false)
+ .ToList();
+
+ var random = new Random(Environment.TickCount + Guid.NewGuid().GetHashCode());
+
+ var candidates = new List<ItemWithTrailer>();
+
+ if (config.EnableIntrosFromMoviesInLibrary)
+ {
+ var itemsWithTrailers = libaryItems
+ .Where(i =>
+ {
+ var hasTrailers = i as IHasTrailers;
+
+ if (hasTrailers != null && hasTrailers.LocalTrailerIds.Count > 0)
+ {
+ if (i is Movie)
+ {
+ return true;
+ }
+ }
+ return false;
+ });
+
+ candidates.AddRange(itemsWithTrailers.Select(i => new ItemWithTrailer
+ {
+ Item = i,
+ Type = ItemWithTrailerType.ItemWithTrailer,
+ User = user,
+ WatchingItem = item,
+ Random = random
+ }));
+ }
+
+ if (config.EnableIntrosFromUpcomingTrailers)
+ {
+ var channelTrailers = await _channelManager.GetAllMediaInternal(new AllChannelMediaQuery
+ {
+ ContentTypes = new[] { ChannelMediaContentType.Trailer },
+ UserId = user.Id.ToString("N")
+
+ }, CancellationToken.None);
+
+ candidates.AddRange(channelTrailers.Items.Select(i => new ItemWithTrailer
+ {
+ Item = i,
+ Type = ItemWithTrailerType.ChannelTrailer,
+ User = user,
+ WatchingItem = item,
+ Random = random
+ }));
+
+ candidates.AddRange(libaryItems.Where(i => i is Trailer).Select(i => new ItemWithTrailer
+ {
+ Item = i,
+ Type = ItemWithTrailerType.LibraryTrailer,
+ User = user,
+ WatchingItem = item,
+ Random = random
+ }));
+ }
+
+ var customIntros = config.EnableCustomIntro ?
+ GetCustomIntros(item) :
+ new List<IntroInfo>();
+
+ var trailerLimit = 2;
+ if (customIntros.Count > 0)
+ {
+ trailerLimit--;
+ }
+
+ // Avoid implicitly captured closure
+ var currentUser = user;
+ return candidates.Where(i =>
+ {
+ if (config.EnableIntrosParentalControl && !FilterByParentalRating(ratingLevel, i.Item))
+ {
+ return false;
+ }
+
+ if (!config.EnableIntrosForWatchedContent && i.IsPlayed)
+ {
+ return false;
+ }
+ return true;
+ })
+ .OrderByDescending(i => i.Score)
+ .ThenBy(i => Guid.NewGuid())
+ .ThenByDescending(i => (i.IsPlayed ? 0 : 1))
+ .Select(i => i.IntroInfo)
+ .Take(trailerLimit)
+ .Concat(customIntros.Take(1));
+ }
+
+ private CinemaModeConfiguration GetOptions()
+ {
+ return _serverConfig.GetConfiguration<CinemaModeConfiguration>("cinemamode");
+ }
+
+ private List<IntroInfo> GetCustomIntros(BaseItem item)
+ {
+ return new List<IntroInfo>();
+ }
+
+ private bool FilterByParentalRating(int? ratingLevel, BaseItem item)
+ {
+ // Only content rated same or lower
+ if (ratingLevel.HasValue)
+ {
+ var level = string.IsNullOrWhiteSpace(item.OfficialRating)
+ ? (int?)null
+ : _localization.GetRatingLevel(item.OfficialRating);
+
+ return level.HasValue && level.Value <= ratingLevel.Value;
+ }
+
+ return true;
+ }
+
+ internal static int GetSimiliarityScore(BaseItem item1, BaseItem item2, Random random)
+ {
+ var points = 0;
+
+ if (!string.IsNullOrEmpty(item1.OfficialRating) && string.Equals(item1.OfficialRating, item2.OfficialRating, StringComparison.OrdinalIgnoreCase))
+ {
+ points += 10;
+ }
+
+ // Find common genres
+ points += item1.Genres.Where(i => item2.Genres.Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10);
+
+ // Find common tags
+ points += GetTags(item1).Where(i => GetTags(item2).Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10);
+
+ // Find common keywords
+ points += GetKeywords(item1).Where(i => GetKeywords(item2).Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10);
+
+ // Find common studios
+ points += item1.Studios.Where(i => item2.Studios.Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 5);
+
+ var item2PeopleNames = item2.People.Select(i => i.Name)
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
+
+ points += item1.People.Where(i => item2PeopleNames.ContainsKey(i.Name)).Sum(i =>
+ {
+ if (string.Equals(i.Type, PersonType.Director, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Director, StringComparison.OrdinalIgnoreCase))
+ {
+ return 5;
+ }
+ if (string.Equals(i.Type, PersonType.Actor, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Actor, StringComparison.OrdinalIgnoreCase))
+ {
+ return 3;
+ }
+ if (string.Equals(i.Type, PersonType.Composer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Composer, StringComparison.OrdinalIgnoreCase))
+ {
+ return 3;
+ }
+ if (string.Equals(i.Type, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase))
+ {
+ return 3;
+ }
+ if (string.Equals(i.Type, PersonType.Writer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Writer, StringComparison.OrdinalIgnoreCase))
+ {
+ return 2;
+ }
+
+ return 1;
+ });
+
+ // Add some randomization so that you're not always seeing the same ones for a given movie
+ points += random.Next(0, 50);
+
+ return points;
+ }
+
+ private static IEnumerable<string> GetTags(BaseItem item)
+ {
+ var hasTags = item as IHasTags;
+ if (hasTags != null)
+ {
+ return hasTags.Tags;
+ }
+
+ return new List<string>();
+ }
+
+ private static IEnumerable<string> GetKeywords(BaseItem item)
+ {
+ var hasTags = item as IHasKeywords;
+ if (hasTags != null)
+ {
+ return hasTags.Keywords;
+ }
+
+ return new List<string>();
+ }
+
+ public IEnumerable<string> GetAllIntroFiles()
+ {
+ return new List<string>();
+ }
+
+ private bool IsSupporter
+ {
+ get { return _security.IsMBSupporter; }
+ }
+
+ public string Name
+ {
+ get { return "Default"; }
+ }
+
+ internal class ItemWithTrailer
+ {
+ internal BaseItem Item;
+ internal ItemWithTrailerType Type;
+ internal User User;
+ internal BaseItem WatchingItem;
+ internal Random Random;
+
+ private bool? _isPlayed;
+ public bool IsPlayed
+ {
+ get
+ {
+ if (!_isPlayed.HasValue)
+ {
+ _isPlayed = Item.IsPlayed(User);
+ }
+ return _isPlayed.Value;
+ }
+ }
+
+ private int? _score;
+ public int Score
+ {
+ get
+ {
+ if (!_score.HasValue)
+ {
+ _score = GetSimiliarityScore(WatchingItem, Item, Random);
+ }
+ return _score.Value;
+ }
+ }
+
+ public IntroInfo IntroInfo
+ {
+ get
+ {
+ var id = Item.Id;
+
+ if (Type == ItemWithTrailerType.ItemWithTrailer)
+ {
+ var hasTrailers = Item as IHasTrailers;
+
+ if (hasTrailers != null)
+ {
+ id = hasTrailers.LocalTrailerIds.FirstOrDefault();
+ }
+ }
+ return new IntroInfo
+ {
+ ItemId = id
+ };
+ }
+ }
+ }
+
+ internal enum ItemWithTrailerType
+ {
+ LibraryTrailer,
+ ChannelTrailer,
+ ItemWithTrailer
+ }
+ }
+
+ public class CinemaModeConfigurationFactory : IConfigurationFactory
+ {
+ public IEnumerable<ConfigurationStore> GetConfigurations()
+ {
+ return new[]
+ {
+ new ConfigurationStore
+ {
+ ConfigurationType = typeof(CinemaModeConfiguration),
+ Key = "cinemamode"
+ }
+ };
+ }
+ }
+
+}
diff --git a/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs b/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
index 7b58dd7c4..e902b939b 100644
--- a/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
+++ b/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
@@ -95,8 +95,7 @@ namespace MediaBrowser.Server.Implementations.Library
return true;
}
- // Don't misidentify xbmc trailers as a movie
- if (filename.IndexOf(BaseItem.XbmcTrailerFileSuffix, StringComparison.OrdinalIgnoreCase) != -1)
+ if (BaseItem.ExtraSuffixes.Any(i => filename.IndexOf(i.Key, StringComparison.OrdinalIgnoreCase) != -1))
{
return true;
}
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index ad5eac033..6283ceb2a 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -1193,14 +1193,43 @@ namespace MediaBrowser.Server.Implementations.Library
/// <param name="item">The item.</param>
/// <param name="user">The user.</param>
/// <returns>IEnumerable{System.String}.</returns>
- public IEnumerable<Video> GetIntros(BaseItem item, User user)
+ public async Task<IEnumerable<Video>> GetIntros(BaseItem item, User user)
{
- return IntroProviders.SelectMany(i => i.GetIntros(item, user))
+ var tasks = IntroProviders
+ .OrderBy(i => (i.GetType().Name.IndexOf("Default", StringComparison.OrdinalIgnoreCase) == -1 ? 1 : 0))
+ .Take(1)
+ .Select(i => GetIntros(i, item, user));
+
+ var items = await Task.WhenAll(tasks).ConfigureAwait(false);
+
+ return items
+ .SelectMany(i => i.ToArray())
.Select(ResolveIntro)
.Where(i => i != null);
}
/// <summary>
+ /// Gets the intros.
+ /// </summary>
+ /// <param name="provider">The provider.</param>
+ /// <param name="item">The item.</param>
+ /// <param name="user">The user.</param>
+ /// <returns>Task&lt;IEnumerable&lt;IntroInfo&gt;&gt;.</returns>
+ private async Task<IEnumerable<IntroInfo>> GetIntros(IIntroProvider provider, BaseItem item, User user)
+ {
+ try
+ {
+ return await provider.GetIntros(item, user).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error getting intros", ex);
+
+ return new List<IntroInfo>();
+ }
+ }
+
+ /// <summary>
/// Gets all intro files.
/// </summary>
/// <returns>IEnumerable{System.String}.</returns>
@@ -1487,7 +1516,7 @@ namespace MediaBrowser.Server.Implementations.Library
var item = GetItemById(id) as UserView;
- if (item == null ||
+ if (item == null ||
!string.Equals(item.Path, path, StringComparison.OrdinalIgnoreCase))
{
Directory.CreateDirectory(path);
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/LocalTrailerResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/LocalTrailerResolver.cs
index b483f7c42..662a9e87c 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/LocalTrailerResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/LocalTrailerResolver.cs
@@ -2,8 +2,10 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Resolvers;
+using MediaBrowser.Model.Entities;
using System;
using System.IO;
+using System.Linq;
namespace MediaBrowser.Server.Implementations.Library.Resolvers
{
@@ -41,9 +43,15 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
}
// Support xbmc local trailer convention, but only when looking for local trailers (hence the parent == null check)
- if (args.Parent == null && _fileSystem.GetFileNameWithoutExtension(args.Path).EndsWith(BaseItem.XbmcTrailerFileSuffix, StringComparison.OrdinalIgnoreCase))
+ if (args.Parent == null)
{
- return base.Resolve(args);
+ var nameWithoutExtension = _fileSystem.GetFileNameWithoutExtension(args.Path);
+ var suffix = BaseItem.ExtraSuffixes.First(i => i.Value == ExtraType.Trailer);
+
+ if (nameWithoutExtension.EndsWith(suffix.Key, StringComparison.OrdinalIgnoreCase))
+ {
+ return base.Resolve(args);
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 215cff22f..51835c1ba 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -111,8 +111,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
}
var filename = Path.GetFileName(args.Path);
- // Don't misidentify xbmc trailers as a movie
- if (filename.IndexOf(BaseItem.XbmcTrailerFileSuffix, StringComparison.OrdinalIgnoreCase) != -1)
+ // Don't misidentify extras or trailers
+ if (BaseItem.ExtraSuffixes.Any(i => filename.IndexOf(i.Key, StringComparison.OrdinalIgnoreCase) != -1))
{
return null;
}
@@ -229,8 +229,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
continue;
}
- // Don't misidentify xbmc trailers as a movie
- if (filename.IndexOf(BaseItem.XbmcTrailerFileSuffix, StringComparison.OrdinalIgnoreCase) != -1)
+ // Don't misidentify extras or trailers as a movie
+ if (BaseItem.ExtraSuffixes.Any(i => filename.IndexOf(i.Key, StringComparison.OrdinalIgnoreCase) != -1))
{
continue;
}
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
index ab4eba16a..c8b4cbb46 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
@@ -569,5 +569,6 @@
"MediaInfoStreamTypeVideo": "Video",
"MediaInfoStreamTypeSubtitle": "Subtitle",
"MediaInfoStreamTypeEmbeddedImage": "Embedded Image",
- "MediaInfoRefFrames": "Ref frames"
+ "MediaInfoRefFrames": "Ref frames",
+ "TabPlayback": "Playback"
}
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json
index ab7bcf37e..e1b3b5ea1 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/server.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json
@@ -288,7 +288,7 @@
"ButtonAutoScroll": "Auto-scroll",
"LabelImageSavingConvention": "Image saving convention:",
"LabelImageSavingConventionHelp": "Media Browser recognizes images from most major media applications. Choosing your downloading convention is useful if you also use other products.",
- "OptionImageSavingCompatible": "Compatible - Media Browser/Xbmc/Plex",
+ "OptionImageSavingCompatible": "Compatible - Media Browser/Kodi/Plex",
"OptionImageSavingStandard": "Standard - MB2",
"ButtonSignIn": "Sign In",
"TitleSignIn": "Sign In",
@@ -883,22 +883,22 @@
"OptionLatestTvRecordings": "Latest recordings",
"LabelProtocolInfo": "Protocol info:",
"LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device.",
- "TabXbmcMetadata": "Xbmc",
- "HeaderXbmcMetadataHelp": "Media Browser includes native support for Xbmc Nfo metadata and images. To enable or disable Xbmc metadata, use the Advanced tab to configure options for your media types.",
- "LabelXbmcMetadataUser": "Add user watch data to nfo's for:",
- "LabelXbmcMetadataUserHelp": "Enable this to keep watch data in sync between Media Browser and Xbmc.",
- "LabelXbmcMetadataDateFormat": "Release date format:",
- "LabelXbmcMetadataDateFormatHelp": "All dates within nfo's will be read and written to using this format.",
- "LabelXbmcMetadataSaveImagePaths": "Save image paths within nfo files",
- "LabelXbmcMetadataSaveImagePathsHelp": "This is recommended if you have image file names that don't conform to Xbmc guidelines.",
- "LabelXbmcMetadataEnablePathSubstitution": "Enable path substitution",
- "LabelXbmcMetadataEnablePathSubstitutionHelp": "Enables path substitution of image paths using the server's path substitution settings.",
- "LabelXbmcMetadataEnablePathSubstitutionHelp2": "See path substitution.",
+ "TabKodiMetadata": "Kodi",
+ "HeaderKodiMetadataHelp": "Media Browser includes native support for Kodi Nfo metadata and images. To enable or disable Kodi metadata, use the Advanced tab to configure options for your media types.",
+ "LabelKodiMetadataUser": "Add user watch data to nfo's for:",
+ "LabelKodiMetadataUserHelp": "Enable this to keep watch data in sync between Media Browser and Kodi.",
+ "LabelKodiMetadataDateFormat": "Release date format:",
+ "LabelKodiMetadataDateFormatHelp": "All dates within nfo's will be read and written to using this format.",
+ "LabelKodiMetadataSaveImagePaths": "Save image paths within nfo files",
+ "LabelKodiMetadataSaveImagePathsHelp": "This is recommended if you have image file names that don't conform to Kodi guidelines.",
+ "LabelKodiMetadataEnablePathSubstitution": "Enable path substitution",
+ "LabelKodiMetadataEnablePathSubstitutionHelp": "Enables path substitution of image paths using the server's path substitution settings.",
+ "LabelKodiMetadataEnablePathSubstitutionHelp2": "See path substitution.",
"LabelGroupChannelsIntoViews": "Display the following channels directly within my views:",
"LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.",
"LabelDisplayCollectionsView": "Display a collections view to show movie collections",
- "LabelXbmcMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs",
- "LabelXbmcMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Xbmc skin compatibility.",
+ "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs",
+ "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.",
"TabServices": "Services",
"TabLogs": "Logs",
"HeaderServerLogFiles": "Server log files:",
@@ -1179,5 +1179,21 @@
"OptionExternallyDownloaded": "External download",
"OptionHlsSegmentedSubtitles": "Hls segmented subtitles",
"LabelSubtitleFormatHelp": "Example: srt",
- "ButtonLearnMore": "Learn more"
+ "ButtonLearnMore": "Learn more",
+ "TabPlayback": "Playback",
+ "HeaderTrailersAndExtras": "Trailers & Extras",
+ "OptionFindTrailers": "Find trailers from the internet automatically",
+ "HeaderLanguagePreferences": "Language Preferences",
+ "TabCinemaMode": "Cinema Mode",
+ "TitlePlayback": "Playback",
+ "LabelEnableCinemaModeFor": "Enable cinema mode for:",
+ "CinemaModeConfigurationHelp": "Cinema mode brings the theater experience straight to your living room with the ability to play trailers and custom intros before the main feature.",
+ "LabelEnableTheFollowingIntros": "Enable the following types of intros:",
+ "OptionTrailersFromMyMovies": "Trailers from movies in my library",
+ "OptionUpcomingMoviesInTheaters": "Trailers from upcoming movies",
+ "LabelLimitIntrosToUnwatchedContent": "Only use trailers from unwatched content",
+ "LabelEnableIntroParentalControl": "Enable smart parental control",
+ "LabelEnableIntroParentalControlHelp": "Intros will only used from content with a parental rating equal to or less than the content being watched.",
+ "LabelEnableTheFollowingIntrosHelp": "Trailers from existing movies requires setup of local trailers. Theater trailers require installation of the Trailer channel plugin.",
+ "ButtonThisFeatureRequiresSupporter": "This feature requires an active supporter membership"
}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index d7c06e2f4..dbecd0a92 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -111,6 +111,7 @@
<Compile Include="Channels\ChannelImageProvider.cs" />
<Compile Include="Channels\ChannelItemImageProvider.cs" />
<Compile Include="Channels\ChannelManager.cs" />
+ <Compile Include="Channels\ChannelPostScanTask.cs" />
<Compile Include="Channels\RefreshChannelsScheduledTask.cs" />
<Compile Include="Collections\CollectionManager.cs" />
<Compile Include="Collections\CollectionsDynamicFolder.cs" />
@@ -173,6 +174,7 @@
<Compile Include="HttpServer\SocketSharp\WebSocketSharpRequest.cs" />
<Compile Include="HttpServer\SocketSharp\WebSocketSharpResponse.cs" />
<Compile Include="HttpServer\ThrottledStream.cs" />
+ <Compile Include="Intros\DefaultIntroProvider.cs" />
<Compile Include="IO\LibraryMonitor.cs" />
<Compile Include="Library\CoreResolutionIgnoreRule.cs" />
<Compile Include="Library\LibraryManager.cs" />
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index a9765889f..358bd6db3 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -571,7 +571,11 @@ namespace MediaBrowser.WebDashboard.Api
"edititemmetadata.js",
"edititemimages.js",
"edititemsubtitles.js",
+
+ "playbackconfiguration.js",
+ "cinemamodeconfiguration.js",
"encodingsettings.js",
+
"externalplayer.js",
"favorites.js",
"gamesrecommendedpage.js",
@@ -610,7 +614,7 @@ namespace MediaBrowser.WebDashboard.Api
"metadataconfigurationpage.js",
"metadataimagespage.js",
"metadatasubtitles.js",
- "metadataxbmc.js",
+ "metadatakodi.js",
"moviegenres.js",
"moviecollections.js",
"movies.js",
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index bf95a42d4..de8505ffc 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -101,6 +101,9 @@
<Content Include="dashboard-ui\channelslatest.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\cinemamodeconfiguration.html">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\css\chromecast.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -161,7 +164,7 @@
<Content Include="dashboard-ui\css\images\clients\playstore.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\css\images\clients\xbmc.png">
+ <Content Include="dashboard-ui\css\images\clients\kodi.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\favicon.ico">
@@ -335,7 +338,7 @@
<Content Include="dashboard-ui\librarypathmapping.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\metadataxbmc.html">
+ <Content Include="dashboard-ui\metadatakodi.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\mypreferencesdisplay.html">
@@ -350,6 +353,9 @@
<Content Include="dashboard-ui\notificationlist.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\playbackconfiguration.html">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\playlistedit.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -608,6 +614,9 @@
<Content Include="dashboard-ui\scripts\chromecast.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\scripts\cinemamodeconfiguration.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\scripts\dashboardgeneral.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -659,7 +668,7 @@
<Content Include="dashboard-ui\scripts\librarypathmapping.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\metadataxbmc.js">
+ <Content Include="dashboard-ui\scripts\metadatakodi.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\mypreferencesdisplay.js">
@@ -674,6 +683,9 @@
<Content Include="dashboard-ui\scripts\notificationlist.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\scripts\playbackconfiguration.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\scripts\playlistedit.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -800,9 +812,6 @@
<Content Include="dashboard-ui\thirdparty\cast_sender.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\thirdparty\jquery-2.0.3.min.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\thirdparty\jquery-2.1.1.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 1b71c1ea7..01b66d7f3 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
- <version>3.0.434</version>
+ <version>3.0.435</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.434" />
+ <dependency id="MediaBrowser.Common" version="3.0.435" />
<dependency id="NLog" version="3.1.0.0" />
<dependency id="SimpleInjector" version="2.5.2" />
<dependency id="sharpcompress" version="0.10.2" />
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index c873587e8..1c9c13bed 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.434</version>
+ <version>3.0.435</version>
<title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec
index a0dc13b7c..a10715f1d 100644
--- a/Nuget/MediaBrowser.Model.Signed.nuspec
+++ b/Nuget/MediaBrowser.Model.Signed.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Model.Signed</id>
- <version>3.0.434</version>
+ <version>3.0.435</version>
<title>MediaBrowser.Model - Signed Edition</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index 3105089d3..dd7651e09 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
- <version>3.0.434</version>
+ <version>3.0.435</version>
<title>Media Browser.Server.Core</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Media Browser Server.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.434" />
+ <dependency id="MediaBrowser.Common" version="3.0.435" />
</dependencies>
</metadata>
<files>