aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2016-08-25 14:46:19 -0400
committerGitHub <noreply@github.com>2016-08-25 14:46:19 -0400
commitba9577f3801105c2f85c061fa7c4c3ee445032ad (patch)
treed06d1da4e2284fcf36c36f7ac1ec84c9613ad812
parent870c843194a8684d1f1098bbed79ecb27cd3478b (diff)
parent1ffd9b31577773d3c87c2b6621c8803b2b17e85c (diff)
Merge pull request #2101 from MediaBrowser/beta
Beta
-rw-r--r--Emby.Drawing/GDI/DynamicImageHelpers.cs48
-rw-r--r--Emby.Drawing/GDI/GDIImageEncoder.cs8
-rw-r--r--MediaBrowser.Api/Library/FileOrganizationService.cs14
-rw-r--r--MediaBrowser.Api/Movies/MoviesService.cs3
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs150
-rw-r--r--MediaBrowser.Api/Playback/Hls/BaseHlsService.cs5
-rw-r--r--MediaBrowser.Api/Playback/StreamRequest.cs2
-rw-r--r--MediaBrowser.Api/Reports/ReportsService.cs2
-rw-r--r--MediaBrowser.Api/Sync/SyncHelper.cs13
-rw-r--r--MediaBrowser.Api/Sync/SyncService.cs3
-rw-r--r--MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs2
-rw-r--r--MediaBrowser.Api/UserLibrary/ItemsService.cs20
-rw-r--r--MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs1
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs22
-rw-r--r--MediaBrowser.Controller/Entities/CollectionFolder.cs1
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs21
-rw-r--r--MediaBrowser.Controller/Entities/TV/Episode.cs46
-rw-r--r--MediaBrowser.Controller/Entities/TV/Season.cs8
-rw-r--r--MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs24
-rw-r--r--MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs1
-rw-r--r--MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs7
-rw-r--r--MediaBrowser.Controller/Providers/BaseItemXmlParser.cs9
-rw-r--r--MediaBrowser.Controller/Session/ISessionManager.cs12
-rw-r--r--MediaBrowser.Dlna/PlayTo/Device.cs10
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlayToController.cs2
-rw-r--r--MediaBrowser.Dlna/Profiles/DefaultProfile.cs1
-rw-r--r--MediaBrowser.Dlna/Profiles/KodiProfile.cs2
-rw-r--r--MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs7
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs118
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs4
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs16
-rw-r--r--MediaBrowser.Model/Configuration/EncodingOptions.cs2
-rw-r--r--MediaBrowser.Model/Configuration/LibraryOptions.cs3
-rw-r--r--MediaBrowser.Model/Configuration/ServerConfiguration.cs2
-rw-r--r--MediaBrowser.Model/Configuration/UserConfiguration.cs3
-rw-r--r--MediaBrowser.Model/Dlna/AudioOptions.cs6
-rw-r--r--MediaBrowser.Model/Dlna/DeviceProfile.cs3
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs48
-rw-r--r--MediaBrowser.Model/Dlna/StreamInfo.cs4
-rw-r--r--MediaBrowser.Model/Dlna/TranscodingProfile.cs3
-rw-r--r--MediaBrowser.Model/Entities/MetadataProviders.cs3
-rw-r--r--MediaBrowser.Model/FileOrganization/FileOrganizationResult.cs6
-rw-r--r--MediaBrowser.Model/Net/MimeTypes.cs2
-rw-r--r--MediaBrowser.Model/Querying/ItemFilter.cs4
-rw-r--r--MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs9
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs2
-rw-r--r--MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs2
-rw-r--r--MediaBrowser.Providers/Photos/PhotoProvider.cs9
-rw-r--r--MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs17
-rw-r--r--MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs3
-rw-r--r--MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs16
-rw-r--r--MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs68
-rw-r--r--MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs100
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs20
-rw-r--r--MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs40
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs6
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj2
-rw-r--r--MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs3
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Session/SessionManager.cs11
-rw-r--r--MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs5
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncNotificationEntryPoint.cs48
-rw-r--r--MediaBrowser.Server.Mac/Emby.Server.Mac.csproj394
-rw-r--r--MediaBrowser.Server.Mono/Native/BaseMonoApp.cs29
-rw-r--r--MediaBrowser.Server.Startup.Common/ApplicationHost.cs3
-rw-r--r--MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj3
-rw-r--r--MediaBrowser.Server.Startup.Common/Migrations/CollectionGroupingMigration.cs40
-rw-r--r--MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs40
-rw-r--r--MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs97
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardService.cs64
-rw-r--r--MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj46
-rw-r--r--MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs9
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs6
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs4
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec4
-rw-r--r--Nuget/MediaBrowser.Common.nuspec2
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec4
78 files changed, 964 insertions, 824 deletions
diff --git a/Emby.Drawing/GDI/DynamicImageHelpers.cs b/Emby.Drawing/GDI/DynamicImageHelpers.cs
index 7b8ef2f98a..59340af8a9 100644
--- a/Emby.Drawing/GDI/DynamicImageHelpers.cs
+++ b/Emby.Drawing/GDI/DynamicImageHelpers.cs
@@ -33,7 +33,9 @@ namespace Emby.Drawing.GDI
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
- graphics.CompositingMode = CompositingMode.SourceCopy;
+
+ // SourceCopy causes the image to be blank in OSX
+ //graphics.CompositingMode = CompositingMode.SourceCopy;
for (var row = 0; row < rows; row++)
{
@@ -44,19 +46,9 @@ namespace Emby.Drawing.GDI
if (files.Count > index)
{
- using (var fileStream = fileSystem.GetFileStream(files[index], FileMode.Open, FileAccess.Read, FileShare.Read, true))
+ using (var imgtemp = Image.FromFile(files[index]))
{
- using (var memoryStream = new MemoryStream())
- {
- fileStream.CopyTo(memoryStream);
-
- memoryStream.Position = 0;
-
- using (var imgtemp = Image.FromStream(memoryStream, true, false))
- {
- graphics.DrawImage(imgtemp, x, y, cellWidth, cellHeight);
- }
- }
+ graphics.DrawImage(imgtemp, x, y, cellWidth, cellHeight);
}
}
@@ -90,7 +82,9 @@ namespace Emby.Drawing.GDI
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
- graphics.CompositingMode = CompositingMode.SourceCopy;
+
+ // SourceCopy causes the image to be blank in OSX
+ //graphics.CompositingMode = CompositingMode.SourceCopy;
for (var row = 0; row < rows; row++)
{
@@ -99,21 +93,10 @@ namespace Emby.Drawing.GDI
var x = col * singleSize;
var y = row * singleSize;
- using (var fileStream = fileSystem.GetFileStream(files[index], FileMode.Open, FileAccess.Read, FileShare.Read, true))
+ using (var imgtemp = Image.FromFile(files[index]))
{
- using (var memoryStream = new MemoryStream())
- {
- fileStream.CopyTo(memoryStream);
-
- memoryStream.Position = 0;
-
- using (var imgtemp = Image.FromStream(memoryStream, true, false))
- {
- graphics.DrawImage(imgtemp, x, y, singleSize, singleSize);
- }
- }
+ graphics.DrawImage(imgtemp, x, y, singleSize, singleSize);
}
-
index++;
}
}
@@ -121,16 +104,5 @@ namespace Emby.Drawing.GDI
}
}
}
-
- private static Stream GetStream(Image image)
- {
- var ms = new MemoryStream();
-
- image.Save(ms, ImageFormat.Png);
-
- ms.Position = 0;
-
- return ms;
- }
}
}
diff --git a/Emby.Drawing/GDI/GDIImageEncoder.cs b/Emby.Drawing/GDI/GDIImageEncoder.cs
index bdd1c5a22f..afd16899dc 100644
--- a/Emby.Drawing/GDI/GDIImageEncoder.cs
+++ b/Emby.Drawing/GDI/GDIImageEncoder.cs
@@ -119,9 +119,11 @@ namespace Emby.Drawing.GDI
thumbnailGraph.SmoothingMode = SmoothingMode.HighQuality;
thumbnailGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
thumbnailGraph.PixelOffsetMode = PixelOffsetMode.HighQuality;
- thumbnailGraph.CompositingMode = !hasPostProcessing ?
- CompositingMode.SourceCopy :
- CompositingMode.SourceOver;
+
+ // SourceCopy causes the image to be blank in OSX
+ //thumbnailGraph.CompositingMode = !hasPostProcessing ?
+ // CompositingMode.SourceCopy :
+ // CompositingMode.SourceOver;
SetBackgroundColor(thumbnailGraph, options);
diff --git a/MediaBrowser.Api/Library/FileOrganizationService.cs b/MediaBrowser.Api/Library/FileOrganizationService.cs
index 0ed08a8607..ca391bef08 100644
--- a/MediaBrowser.Api/Library/FileOrganizationService.cs
+++ b/MediaBrowser.Api/Library/FileOrganizationService.cs
@@ -154,9 +154,12 @@ namespace MediaBrowser.Api.Library
public void Post(PerformOrganization request)
{
+ // Don't await this
var task = _iFileOrganizationService.PerformOrganization(request.Id);
- Task.WaitAll(task);
+ // Async processing (close dialog early instead of waiting until the file has been copied)
+ // Wait 2s for exceptions that may occur to have them forwarded to the client for immediate error display
+ task.Wait(2000);
}
public void Post(OrganizeEpisode request)
@@ -168,6 +171,7 @@ namespace MediaBrowser.Api.Library
dicNewProviderIds = request.NewSeriesProviderIds;
}
+ // Don't await this
var task = _iFileOrganizationService.PerformEpisodeOrganization(new EpisodeFileOrganizationRequest
{
EndingEpisodeNumber = request.EndingEpisodeNumber,
@@ -182,11 +186,9 @@ namespace MediaBrowser.Api.Library
TargetFolder = request.TargetFolder
});
- // For async processing (close dialog early instead of waiting until the file has been copied)
- //var tasks = new Task[] { task };
- //Task.WaitAll(tasks, 8000);
-
- Task.WaitAll(task);
+ // Async processing (close dialog early instead of waiting until the file has been copied)
+ // Wait 2s for exceptions that may occur to have them forwarded to the client for immediate error display
+ task.Wait(2000);
}
public object Get(GetSmartMatchInfos request)
diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs
index 755713c845..66f2fac812 100644
--- a/MediaBrowser.Api/Movies/MoviesService.cs
+++ b/MediaBrowser.Api/Movies/MoviesService.cs
@@ -192,7 +192,8 @@ namespace MediaBrowser.Api.Movies
SortOrder = SortOrder.Descending,
Limit = 7,
ParentId = parentIdGuid,
- Recursive = true
+ Recursive = true,
+ IsPlayed = true
};
var recentlyPlayedMovies = _libraryManager.GetItemList(query).ToList();
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index f52505c04b..a022c83d84 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -298,7 +298,8 @@ namespace MediaBrowser.Api.Playback
// Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this.
if (state.VideoType == VideoType.VideoFile)
{
- var hwType = ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType;
+ var encodingOptions = ApiEntryPoint.Instance.GetEncodingOptions();
+ var hwType = encodingOptions.HardwareAccelerationType;
if (string.Equals(hwType, "qsv", StringComparison.OrdinalIgnoreCase) ||
string.Equals(hwType, "h264_qsv", StringComparison.OrdinalIgnoreCase))
@@ -314,6 +315,10 @@ namespace MediaBrowser.Api.Playback
{
return GetAvailableEncoder("h264_omx", defaultEncoder);
}
+ if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(encodingOptions.VaapiDevice))
+ {
+ return GetAvailableEncoder("h264_vaapi", defaultEncoder);
+ }
}
return defaultEncoder;
@@ -427,7 +432,8 @@ namespace MediaBrowser.Api.Playback
if (!string.IsNullOrEmpty(state.VideoRequest.Profile))
{
- if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase))
+ if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) &&
+ !string.Equals(videoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{
// not supported by h264_omx
param += " -profile:v " + state.VideoRequest.Profile;
@@ -482,7 +488,8 @@ namespace MediaBrowser.Api.Playback
if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) &&
- !string.Equals(videoCodec, "h264_nvenc", StringComparison.OrdinalIgnoreCase))
+ !string.Equals(videoCodec, "h264_nvenc", StringComparison.OrdinalIgnoreCase) &&
+ !string.Equals(videoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{
param = "-pix_fmt yuv420p " + param;
}
@@ -548,59 +555,97 @@ namespace MediaBrowser.Api.Playback
var filters = new List<string>();
- if (state.DeInterlace)
+ if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
+ {
+ filters.Add("format=nv12|vaapi");
+ filters.Add("hwupload");
+ }
+ else if (state.DeInterlace && !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{
filters.Add("yadif=0:-1:0");
}
- // If fixed dimensions were supplied
- if (request.Width.HasValue && request.Height.HasValue)
+ if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{
- var widthParam = request.Width.Value.ToString(UsCulture);
- var heightParam = request.Height.Value.ToString(UsCulture);
+ // Work around vaapi's reduced scaling features
+ var scaler = "scale_vaapi";
- filters.Add(string.Format("scale=trunc({0}/2)*2:trunc({1}/2)*2", widthParam, heightParam));
- }
+ // Given the input dimensions (inputWidth, inputHeight), determine the output dimensions
+ // (outputWidth, outputHeight). The user may request precise output dimensions or maximum
+ // output dimensions. Output dimensions are guaranteed to be even.
+ decimal inputWidth = Convert.ToDecimal(state.VideoStream.Width);
+ decimal inputHeight = Convert.ToDecimal(state.VideoStream.Height);
+ decimal outputWidth = request.Width.HasValue ? Convert.ToDecimal(request.Width.Value) : inputWidth;
+ decimal outputHeight = request.Height.HasValue ? Convert.ToDecimal(request.Height.Value) : inputHeight;
+ decimal maximumWidth = request.MaxWidth.HasValue ? Convert.ToDecimal(request.MaxWidth.Value) : outputWidth;
+ decimal maximumHeight = request.MaxHeight.HasValue ? Convert.ToDecimal(request.MaxHeight.Value) : outputHeight;
- // If Max dimensions were supplied, for width selects lowest even number between input width and width req size and selects lowest even number from in width*display aspect and requested size
- else if (request.MaxWidth.HasValue && request.MaxHeight.HasValue)
- {
- var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture);
- var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture);
+ if (outputWidth > maximumWidth || outputHeight > maximumHeight)
+ {
+ var scale = Math.Min(maximumWidth / outputWidth, maximumHeight / outputHeight);
+ outputWidth = Math.Min(maximumWidth, Math.Truncate(outputWidth * scale));
+ outputHeight = Math.Min(maximumHeight, Math.Truncate(outputHeight * scale));
+ }
- filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/2)*2:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", maxWidthParam, maxHeightParam));
- }
+ outputWidth = 2 * Math.Truncate(outputWidth / 2);
+ outputHeight = 2 * Math.Truncate(outputHeight / 2);
- // If a fixed width was requested
- else if (request.Width.HasValue)
+ if (outputWidth != inputWidth || outputHeight != inputHeight)
+ {
+ filters.Add(string.Format("{0}=w={1}:h={2}", scaler, outputWidth.ToString(UsCulture), outputHeight.ToString(UsCulture)));
+ }
+ }
+ else
{
- var widthParam = request.Width.Value.ToString(UsCulture);
+ // If fixed dimensions were supplied
+ if (request.Width.HasValue && request.Height.HasValue)
+ {
+ var widthParam = request.Width.Value.ToString(UsCulture);
+ var heightParam = request.Height.Value.ToString(UsCulture);
- filters.Add(string.Format("scale={0}:trunc(ow/a/2)*2", widthParam));
- }
+ filters.Add(string.Format("scale=trunc({0}/2)*2:trunc({1}/2)*2", widthParam, heightParam));
+ }
- // If a fixed height was requested
- else if (request.Height.HasValue)
- {
- var heightParam = request.Height.Value.ToString(UsCulture);
+ // If Max dimensions were supplied, for width selects lowest even number between input width and width req size and selects lowest even number from in width*display aspect and requested size
+ else if (request.MaxWidth.HasValue && request.MaxHeight.HasValue)
+ {
+ var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture);
+ var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture);
- filters.Add(string.Format("scale=trunc(oh*a/2)*2:{0}", heightParam));
- }
+ filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/2)*2:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", maxWidthParam, maxHeightParam));
+ }
- // If a max width was requested
- else if (request.MaxWidth.HasValue)
- {
- var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture);
+ // If a fixed width was requested
+ else if (request.Width.HasValue)
+ {
+ var widthParam = request.Width.Value.ToString(UsCulture);
- filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,{0})/2)*2:trunc(ow/dar/2)*2", maxWidthParam));
- }
+ filters.Add(string.Format("scale={0}:trunc(ow/a/2)*2", widthParam));
+ }
- // If a max height was requested
- else if (request.MaxHeight.HasValue)
- {
- var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture);
+ // If a fixed height was requested
+ else if (request.Height.HasValue)
+ {
+ var heightParam = request.Height.Value.ToString(UsCulture);
- filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(ih\\,{0})", maxHeightParam));
+ filters.Add(string.Format("scale=trunc(oh*a/2)*2:{0}", heightParam));
+ }
+
+ // If a max width was requested
+ else if (request.MaxWidth.HasValue)
+ {
+ var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture);
+
+ filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,{0})/2)*2:trunc(ow/dar/2)*2", maxWidthParam));
+ }
+
+ // If a max height was requested
+ else if (request.MaxHeight.HasValue)
+ {
+ var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture);
+
+ filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(max(iw/dar\\,ih)\\,{0})", maxHeightParam));
+ }
}
var output = string.Empty;
@@ -935,6 +980,17 @@ namespace MediaBrowser.Api.Playback
}
}
+ if (state.VideoRequest != null)
+ {
+ var encodingOptions = ApiEntryPoint.Instance.GetEncodingOptions();
+ if (GetVideoEncoder(state).IndexOf("vaapi", StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ arg = "-hwaccel vaapi -hwaccel_output_format vaapi -vaapi_device " + encodingOptions.VaapiDevice + " " + arg;
+ }
+ }
+
+ arg += string.Format(" -ss {0}", MediaEncoder.GetTimeParameter(TimeSpan.FromSeconds(1).Ticks));
+
return arg.Trim();
}
@@ -1590,13 +1646,6 @@ namespace MediaBrowser.Api.Playback
}
else if (i == 25)
{
- if (videoRequest != null)
- {
- videoRequest.ForceLiveStream = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
- }
- }
- else if (i == 26)
- {
if (!string.IsNullOrWhiteSpace(val) && videoRequest != null)
{
SubtitleDeliveryMethod method;
@@ -1606,18 +1655,18 @@ namespace MediaBrowser.Api.Playback
}
}
}
- else if (i == 27)
+ else if (i == 26)
{
request.TranscodingMaxAudioChannels = int.Parse(val, UsCulture);
}
- else if (i == 28)
+ else if (i == 27)
{
if (videoRequest != null)
{
videoRequest.EnableSubtitlesInManifest = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
}
}
- else if (i == 29)
+ else if (i == 28)
{
request.Tag = val;
}
@@ -2218,7 +2267,6 @@ namespace MediaBrowser.Api.Playback
if (state.VideoRequest != null)
{
state.VideoRequest.CopyTimestamps = transcodingProfile.CopyTimestamps;
- state.VideoRequest.ForceLiveStream = transcodingProfile.ForceLiveStream;
state.VideoRequest.EnableSubtitlesInManifest = transcodingProfile.EnableSubtitlesInManifest;
}
}
@@ -2244,7 +2292,7 @@ namespace MediaBrowser.Api.Playback
return Task.FromResult(true);
}
- if (!string.Equals(MediaEncoder.EncoderLocationType, "Default", StringComparison.OrdinalIgnoreCase))
+ if (!MediaEncoder.IsDefaultEncoderPath)
{
return Task.FromResult(true);
}
diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
index 4ec14c96cb..a0ac96b9d2 100644
--- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
@@ -281,11 +281,6 @@ namespace MediaBrowser.Api.Playback.Hls
{
var isLiveStream = (state.RunTimeTicks ?? 0) == 0;
- if (state.VideoRequest.ForceLiveStream)
- {
- return true;
- }
-
return isLiveStream;
}
}
diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs
index e1a577f525..8cdf846ed5 100644
--- a/MediaBrowser.Api/Playback/StreamRequest.cs
+++ b/MediaBrowser.Api/Playback/StreamRequest.cs
@@ -193,8 +193,6 @@ namespace MediaBrowser.Api.Playback
[ApiMember(Name = "CopyTimestamps", Description = "Whether or not to copy timestamps when transcoding with an offset. Defaults to false.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool CopyTimestamps { get; set; }
- public bool ForceLiveStream { get; set; }
-
public bool EnableSubtitlesInManifest { get; set; }
public VideoStreamRequest()
diff --git a/MediaBrowser.Api/Reports/ReportsService.cs b/MediaBrowser.Api/Reports/ReportsService.cs
index d0b6d6e787..cb03d93822 100644
--- a/MediaBrowser.Api/Reports/ReportsService.cs
+++ b/MediaBrowser.Api/Reports/ReportsService.cs
@@ -275,8 +275,6 @@ namespace MediaBrowser.Api.Reports
case ItemFilter.IsPlayed:
query.IsPlayed = true;
break;
- case ItemFilter.IsRecentlyAdded:
- break;
case ItemFilter.IsResumable:
query.IsResumable = true;
break;
diff --git a/MediaBrowser.Api/Sync/SyncHelper.cs b/MediaBrowser.Api/Sync/SyncHelper.cs
index 2f857000c0..60df2bb1e9 100644
--- a/MediaBrowser.Api/Sync/SyncHelper.cs
+++ b/MediaBrowser.Api/Sync/SyncHelper.cs
@@ -24,6 +24,19 @@ namespace MediaBrowser.Api.Sync
}
break;
}
+ if (item.IsAudio)
+ {
+ options.Add(SyncJobOption.Quality);
+ options.Add(SyncJobOption.Profile);
+ break;
+ }
+ if (item.IsMusicGenre || item.IsArtist|| item.IsType("musicalbum"))
+ {
+ options.Add(SyncJobOption.Quality);
+ options.Add(SyncJobOption.Profile);
+ options.Add(SyncJobOption.ItemLimit);
+ break;
+ }
if (item.IsFolderItem && !item.IsMusicGenre && !item.IsArtist && !item.IsType("musicalbum") && !item.IsGameGenre)
{
options.Add(SyncJobOption.Quality);
diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs
index b9544d71ba..821591dc4e 100644
--- a/MediaBrowser.Api/Sync/SyncService.cs
+++ b/MediaBrowser.Api/Sync/SyncService.cs
@@ -291,7 +291,8 @@ namespace MediaBrowser.Api.Sync
{
Fields = new List<ItemFields>
{
- ItemFields.SyncInfo
+ ItemFields.SyncInfo,
+ ItemFields.BasicSyncInfo
}
};
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
index 94a6a7ef13..5381f9004c 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
@@ -164,8 +164,6 @@ namespace MediaBrowser.Api.UserLibrary
case ItemFilter.IsPlayed:
query.IsPlayed = true;
break;
- case ItemFilter.IsRecentlyAdded:
- break;
case ItemFilter.IsResumable:
query.IsResumable = true;
break;
diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index ce7905b42f..681624ba22 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -149,24 +149,6 @@ namespace MediaBrowser.Api.UserLibrary
item = user == null ? _libraryManager.RootFolder : user.RootFolder;
}
- if (!string.IsNullOrEmpty(request.Ids))
- {
- var query = GetItemsQuery(request, user);
- var specificItems = _libraryManager.GetItemList(query).ToArray();
- if (query.SortBy.Length == 0)
- {
- var ids = query.ItemIds.ToList();
-
- // Try to preserve order
- specificItems = specificItems.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToArray();
- }
- return new QueryResult<BaseItem>
- {
- Items = specificItems.ToArray(),
- TotalRecordCount = specificItems.Length
- };
- }
-
// Default list type = children
var folder = item as Folder;
@@ -289,8 +271,6 @@ namespace MediaBrowser.Api.UserLibrary
case ItemFilter.IsPlayed:
query.IsPlayed = true;
break;
- case ItemFilter.IsRecentlyAdded:
- break;
case ItemFilter.IsResumable:
query.IsResumable = true;
break;
diff --git a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs
index d1ec30210e..a118f7c265 100644
--- a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs
+++ b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs
@@ -33,7 +33,6 @@ namespace MediaBrowser.Common.Implementations.Updates
EnableKeepAlive = false,
CancellationToken = cancellationToken,
UserAgent = "Emby/3.0"
-
};
if (_cacheLength.Ticks > 0)
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index cbbb9a89a3..984374a499 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -281,6 +281,20 @@ namespace MediaBrowser.Controller.Entities
}
}
+ public Task UpdateIsOffline(bool newValue)
+ {
+ var item = this;
+
+ if (item.IsOffline != newValue)
+ {
+ item.IsOffline = newValue;
+ // this is creating too many repeated db updates
+ //return item.UpdateToRepository(ItemUpdateType.None, CancellationToken.None);
+ }
+
+ return Task.FromResult(true);
+ }
+
/// <summary>
/// Gets or sets the type of the location.
/// </summary>
@@ -290,10 +304,10 @@ namespace MediaBrowser.Controller.Entities
{
get
{
- if (IsOffline)
- {
- return LocationType.Offline;
- }
+ //if (IsOffline)
+ //{
+ // return LocationType.Offline;
+ //}
if (string.IsNullOrWhiteSpace(Path))
{
diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs
index e120f2e23d..597ecf973a 100644
--- a/MediaBrowser.Controller/Entities/CollectionFolder.cs
+++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs
@@ -106,6 +106,7 @@ namespace MediaBrowser.Controller.Entities
{
LibraryOptions[path] = options;
+ options.SchemaVersion = 1;
XmlSerializer.SerializeToFile(options, GetLibraryOptionsPath(path));
}
}
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index b5c76c0ebc..bf47ada0dc 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -375,7 +375,7 @@ namespace MediaBrowser.Controller.Entities
if (currentChildren.TryGetValue(child.Id, out currentChild) && IsValidFromResolver(currentChild, child))
{
- await UpdateIsOffline(currentChild, false).ConfigureAwait(false);
+ await currentChild.UpdateIsOffline(false).ConfigureAwait(false);
validChildren.Add(currentChild);
continue;
@@ -404,7 +404,7 @@ namespace MediaBrowser.Controller.Entities
else if (!string.IsNullOrEmpty(item.Path) && IsPathOffline(item.Path))
{
- await UpdateIsOffline(item, true).ConfigureAwait(false);
+ await item.UpdateIsOffline(true).ConfigureAwait(false);
}
else
{
@@ -461,17 +461,6 @@ namespace MediaBrowser.Controller.Entities
progress.Report(100);
}
- private Task UpdateIsOffline(BaseItem item, bool newValue)
- {
- if (item.IsOffline != newValue)
- {
- item.IsOffline = newValue;
- return item.UpdateToRepository(ItemUpdateType.None, CancellationToken.None);
- }
-
- return Task.FromResult(true);
- }
-
private async Task RefreshMetadataRecursive(MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
{
var children = ActualChildren.ToList();
@@ -902,16 +891,16 @@ namespace MediaBrowser.Controller.Entities
{
if (query.ItemIds.Length > 0)
{
- var specificItems = query.ItemIds.Select(LibraryManager.GetItemById).Where(i => i != null).ToList();
+ var result = LibraryManager.GetItemsResult(query);
if (query.SortBy.Length == 0)
{
var ids = query.ItemIds.ToList();
// Try to preserve order
- specificItems = specificItems.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToList();
+ result.Items = result.Items.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToArray();
}
- return Task.FromResult(PostFilterAndSort(specificItems, query, true, true));
+ return Task.FromResult(result);
}
return GetItemsInternal(query);
diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs
index 726390f65e..1a02043d6f 100644
--- a/MediaBrowser.Controller/Entities/TV/Episode.cs
+++ b/MediaBrowser.Controller/Entities/TV/Episode.cs
@@ -135,7 +135,11 @@ namespace MediaBrowser.Controller.Entities.TV
[IgnoreDataMember]
public Series Series
{
- get { return FindParent<Series>(); }
+ get
+ {
+ var seriesId = SeriesId ?? FindSeriesId();
+ return seriesId.HasValue ? (LibraryManager.GetItemById(seriesId.Value) as Series) : null;
+ }
}
[IgnoreDataMember]
@@ -143,24 +147,8 @@ namespace MediaBrowser.Controller.Entities.TV
{
get
{
- 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;
+ var seasonId = SeasonId ?? FindSeasonId();
+ return seasonId.HasValue ? (LibraryManager.GetItemById(seasonId.Value) as Season) : null;
}
}
@@ -193,7 +181,23 @@ namespace MediaBrowser.Controller.Entities.TV
public Guid? FindSeasonId()
{
- var season = Season;
+ 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;
}
@@ -263,7 +267,7 @@ namespace MediaBrowser.Controller.Entities.TV
public Guid? FindSeriesId()
{
- var series = Series;
+ var series = FindParent<Series>();
return series == null ? (Guid?)null : series.Id;
}
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index 842b2fd602..65b7c9955b 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -99,7 +99,11 @@ namespace MediaBrowser.Controller.Entities.TV
[IgnoreDataMember]
public Series Series
{
- get { return FindParent<Series>(); }
+ get
+ {
+ var seriesId = SeriesId ?? FindSeriesId();
+ return seriesId.HasValue ? (LibraryManager.GetItemById(seriesId.Value) as Series) : null;
+ }
}
[IgnoreDataMember]
@@ -241,7 +245,7 @@ namespace MediaBrowser.Controller.Entities.TV
public Guid? FindSeriesId()
{
- var series = Series;
+ var series = FindParent<Series>();
return series == null ? (Guid?)null : series.Id;
}
diff --git a/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs b/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs
index daa670d836..9a5b96a241 100644
--- a/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs
+++ b/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs
@@ -1,5 +1,7 @@
-using MediaBrowser.Model.FileOrganization;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.FileOrganization;
using MediaBrowser.Model.Querying;
+using System;
using System.Threading;
using System.Threading.Tasks;
@@ -7,6 +9,11 @@ namespace MediaBrowser.Controller.FileOrganization
{
public interface IFileOrganizationService
{
+ event EventHandler<GenericEventArgs<FileOrganizationResult>> ItemAdded;
+ event EventHandler<GenericEventArgs<FileOrganizationResult>> ItemUpdated;
+ event EventHandler<GenericEventArgs<FileOrganizationResult>> ItemRemoved;
+ event EventHandler LogReset;
+
/// <summary>
/// Processes the new files.
/// </summary>
@@ -81,5 +88,20 @@ namespace MediaBrowser.Controller.FileOrganization
/// <param name="ItemName">Item name.</param>
/// <param name="matchString">The match string to delete.</param>
void DeleteSmartMatchEntry(string ItemName, string matchString);
+
+ /// <summary>
+ /// Attempts to add a an item to the list of currently processed items.
+ /// </summary>
+ /// <param name="result">The result item.</param>
+ /// <param name="fullClientRefresh">Passing true will notify the client to reload all items, otherwise only a single item will be refreshed.</param>
+ /// <returns>True if the item was added, False if the item is already contained in the list.</returns>
+ bool AddToInProgressList(FileOrganizationResult result, bool fullClientRefresh);
+
+ /// <summary>
+ /// Removes an item from the list of currently processed items.
+ /// </summary>
+ /// <param name="result">The result item.</param>
+ /// <returns>True if the item was removed, False if the item was not contained in the list.</returns>
+ bool RemoveFromInprogressList(FileOrganizationResult result);
}
}
diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
index 1fef8bead7..7fdbf020ce 100644
--- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
+++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
@@ -134,5 +134,6 @@ namespace MediaBrowser.Controller.MediaEncoding
Task UpdateEncoderPath(string path, string pathType);
bool SupportsEncoder(string encoder);
+ bool IsDefaultEncoderPath { get; }
}
}
diff --git a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs
index 66a9fa60b8..96a3753e19 100644
--- a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs
+++ b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs
@@ -36,8 +36,13 @@ namespace MediaBrowser.Controller.MediaEncoding
return new[] {videoPath};
}
- public static List<string> GetPlayableStreamFiles(IFileSystem fileSystem, string rootPath, IEnumerable<string> filenames)
+ private static List<string> GetPlayableStreamFiles(IFileSystem fileSystem, string rootPath, List<string> filenames)
{
+ if (filenames.Count == 0)
+ {
+ return new List<string>();
+ }
+
var allFiles = fileSystem
.GetFilePaths(rootPath, true)
.ToList();
diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
index a783910e34..c0912708c3 100644
--- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
+++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
@@ -724,6 +724,15 @@ namespace MediaBrowser.Controller.Providers
}
break;
}
+ case "TvMazeId":
+ {
+ var id = reader.ReadElementContentAsString();
+ if (!string.IsNullOrWhiteSpace(id))
+ {
+ item.SetProviderId(MetadataProviders.TvMaze, id);
+ }
+ break;
+ }
case "AudioDbArtistId":
{
var id = reader.ReadElementContentAsString();
diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs
index 6659d15530..3871952450 100644
--- a/MediaBrowser.Controller/Session/ISessionManager.cs
+++ b/MediaBrowser.Controller/Session/ISessionManager.cs
@@ -172,15 +172,21 @@ namespace MediaBrowser.Controller.Session
Task SendPlaystateCommand(string controllingSessionId, string sessionId, PlaystateRequest command, CancellationToken cancellationToken);
/// <summary>
- /// Sends the message to user sessions.
+ /// Sends the message to admin sessions.
/// </summary>
/// <typeparam name="T"></typeparam>
- /// <param name="userId">The user identifier.</param>
/// <param name="name">The name.</param>
/// <param name="data">The data.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- Task SendMessageToUserSessions<T>(string userId, string name, T data, CancellationToken cancellationToken);
+ Task SendMessageToAdminSessions<T>(string name, T data, CancellationToken cancellationToken);
+
+ /// <summary>
+ /// Sends the message to user sessions.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns>Task.</returns>
+ Task SendMessageToUserSessions<T>(List<string> userIds, string name, T data, CancellationToken cancellationToken);
/// <summary>
/// Sends the message to user device sessions.
diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs
index 6ad5899da1..174ca871a4 100644
--- a/MediaBrowser.Dlna/PlayTo/Device.cs
+++ b/MediaBrowser.Dlna/PlayTo/Device.cs
@@ -479,17 +479,17 @@ namespace MediaBrowser.Dlna.PlayTo
_successiveStopCount++;
_connectFailureCount++;
- if (_successiveStopCount >= maxSuccessiveStopReturns)
- {
- RestartTimerInactive();
- }
- if (_connectFailureCount >= maxSuccessiveStopReturns)
+ if (_connectFailureCount >= 3)
{
if (OnDeviceUnavailable != null)
{
OnDeviceUnavailable();
}
}
+ if (_successiveStopCount >= maxSuccessiveStopReturns)
+ {
+ RestartTimerInactive();
+ }
}
catch (Exception ex)
{
diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs
index 7429330bd6..913b34016d 100644
--- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs
@@ -99,11 +99,11 @@ namespace MediaBrowser.Dlna.PlayTo
public void Init(Device device)
{
_device = device;
+ _device.OnDeviceUnavailable = OnDeviceUnavailable;
_device.PlaybackStart += _device_PlaybackStart;
_device.PlaybackProgress += _device_PlaybackProgress;
_device.PlaybackStopped += _device_PlaybackStopped;
_device.MediaChanged += _device_MediaChanged;
- _device.OnDeviceUnavailable = OnDeviceUnavailable;
_device.Start();
diff --git a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs
index e4f6d337fe..5f60e8306d 100644
--- a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs
@@ -33,7 +33,6 @@ namespace MediaBrowser.Dlna.Profiles
MaxStreamingBitrate = 20000000;
MaxStaticBitrate = 20000000;
MusicStreamingTranscodingBitrate = 192000;
- MusicSyncBitrate = 192000;
EnableAlbumArtInDidl = false;
diff --git a/MediaBrowser.Dlna/Profiles/KodiProfile.cs b/MediaBrowser.Dlna/Profiles/KodiProfile.cs
index 184923b70d..5e1ac57608 100644
--- a/MediaBrowser.Dlna/Profiles/KodiProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/KodiProfile.cs
@@ -11,9 +11,7 @@ namespace MediaBrowser.Dlna.Profiles
Name = "Kodi";
MaxStreamingBitrate = 100000000;
- MaxStaticBitrate = 100000000;
MusicStreamingTranscodingBitrate = 1280000;
- MusicSyncBitrate = 1280000;
TimelineOffsetSeconds = 5;
diff --git a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs
index 2b3f53aeb5..d472d48121 100644
--- a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs
+++ b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs
@@ -553,6 +553,13 @@ namespace MediaBrowser.LocalMetadata.Savers
builder.Append("<TVRageId>" + SecurityElement.Escape(externalId) + "</TVRageId>");
}
+ externalId = item.GetProviderId(MetadataProviders.TvMaze);
+
+ if (!string.IsNullOrEmpty(externalId))
+ {
+ builder.Append("<TvMazeId>" + SecurityElement.Escape(externalId) + "</TvMazeId>");
+ }
+
var hasTagline = item as IHasTaglines;
if (hasTagline != null)
{
diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
index 32cd950afe..6bf414dfa4 100644
--- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
@@ -680,7 +680,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (!string.IsNullOrEmpty(state.Options.Profile))
{
- if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase))
+ if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) &&
+ !string.Equals(videoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{
// not supported by h264_omx
param += " -profile:v " + state.Options.Profile;
@@ -737,7 +738,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) &&
- !string.Equals(videoCodec, "h264_nvenc", StringComparison.OrdinalIgnoreCase))
+ !string.Equals(videoCodec, "h264_nvenc", StringComparison.OrdinalIgnoreCase) &&
+ !string.Equals(videoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{
param = "-pix_fmt yuv420p " + param;
}
@@ -887,66 +889,96 @@ namespace MediaBrowser.MediaEncoding.Encoder
var filters = new List<string>();
- if (state.DeInterlace)
+ if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
+ {
+ filters.Add("format=nv12|vaapi");
+ filters.Add("hwupload");
+ }
+ else if (state.DeInterlace && !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{
filters.Add("yadif=0:-1:0");
}
- // If fixed dimensions were supplied
- if (request.Width.HasValue && request.Height.HasValue)
+ if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{
- var widthParam = request.Width.Value.ToString(UsCulture);
- var heightParam = request.Height.Value.ToString(UsCulture);
+ // Work around vaapi's reduced scaling features
+ var scaler = "scale_vaapi";
- filters.Add(string.Format("scale=trunc({0}/2)*2:trunc({1}/2)*2", widthParam, heightParam));
- }
+ // Given the input dimensions (inputWidth, inputHeight), determine the output dimensions
+ // (outputWidth, outputHeight). The user may request precise output dimensions or maximum
+ // output dimensions. Output dimensions are guaranteed to be even.
+ decimal inputWidth = Convert.ToDecimal(state.VideoStream.Width);
+ decimal inputHeight = Convert.ToDecimal(state.VideoStream.Height);
+ decimal outputWidth = request.Width.HasValue ? Convert.ToDecimal(request.Width.Value) : inputWidth;
+ decimal outputHeight = request.Height.HasValue ? Convert.ToDecimal(request.Height.Value) : inputHeight;
+ decimal maximumWidth = request.MaxWidth.HasValue ? Convert.ToDecimal(request.MaxWidth.Value) : outputWidth;
+ decimal maximumHeight = request.MaxHeight.HasValue ? Convert.ToDecimal(request.MaxHeight.Value) : outputHeight;
- // If Max dimensions were supplied, for width selects lowest even number between input width and width req size and selects lowest even number from in width*display aspect and requested size
- else if (request.MaxWidth.HasValue && request.MaxHeight.HasValue)
- {
- var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture);
- var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture);
+ if (outputWidth > maximumWidth || outputHeight > maximumHeight)
+ {
+ var scale = Math.Min(maximumWidth / outputWidth, maximumHeight / outputHeight);
+ outputWidth = Math.Min(maximumWidth, Math.Truncate(outputWidth * scale));
+ outputHeight = Math.Min(maximumHeight, Math.Truncate(outputHeight * scale));
+ }
- filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/2)*2:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", maxWidthParam, maxHeightParam));
- }
+ outputWidth = 2 * Math.Truncate(outputWidth / 2);
+ outputHeight = 2 * Math.Truncate(outputHeight / 2);
- // If a fixed width was requested
- else if (request.Width.HasValue)
+ if (outputWidth != inputWidth || outputHeight != inputHeight)
+ {
+ filters.Add(string.Format("{0}=w={1}:h={2}", scaler, outputWidth.ToString(UsCulture), outputHeight.ToString(UsCulture)));
+ }
+ }
+ else
{
- var widthParam = request.Width.Value.ToString(UsCulture);
+ // If fixed dimensions were supplied
+ if (request.Width.HasValue && request.Height.HasValue)
+ {
+ var widthParam = request.Width.Value.ToString(UsCulture);
+ var heightParam = request.Height.Value.ToString(UsCulture);
- filters.Add(string.Format("scale={0}:trunc(ow/a/2)*2", widthParam));
- }
+ filters.Add(string.Format("scale=trunc({0}/2)*2:trunc({1}/2)*2", widthParam, heightParam));
+ }
- // If a fixed height was requested
- else if (request.Height.HasValue)
- {
- var heightParam = request.Height.Value.ToString(UsCulture);
+ // If Max dimensions were supplied, for width selects lowest even number between input width and width req size and selects lowest even number from in width*display aspect and requested size
+ else if (request.MaxWidth.HasValue && request.MaxHeight.HasValue)
+ {
+ var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture);
+ var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture);
- filters.Add(string.Format("scale=trunc(oh*a/2)*2:{0}", heightParam));
- }
+ filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/2)*2:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", maxWidthParam, maxHeightParam));
+ }
- // If a max width was requested
- else if (request.MaxWidth.HasValue)
- {
- var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture);
+ // If a fixed width was requested
+ else if (request.Width.HasValue)
+ {
+ var widthParam = request.Width.Value.ToString(UsCulture);
- filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,{0})/2)*2:trunc(ow/dar/2)*2", maxWidthParam));
- }
+ filters.Add(string.Format("scale={0}:trunc(ow/a/2)*2", widthParam));
+ }
- // If a max height was requested
- else if (request.MaxHeight.HasValue)
- {
- var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture);
+ // If a fixed height was requested
+ else if (request.Height.HasValue)
+ {
+ var heightParam = request.Height.Value.ToString(UsCulture);
- filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(ih\\,{0})", maxHeightParam));
- }
+ filters.Add(string.Format("scale=trunc(oh*a/2)*2:{0}", heightParam));
+ }
- if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
- {
- if (filters.Count > 1)
+ // If a max width was requested
+ else if (request.MaxWidth.HasValue)
+ {
+ var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture);
+
+ filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,{0})/2)*2:trunc(ow/dar/2)*2", maxWidthParam));
+ }
+
+ // If a max height was requested
+ else if (request.MaxHeight.HasValue)
{
- //filters[filters.Count - 1] += ":flags=fast_bilinear";
+ var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture);
+
+ filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(max(iw/dar\\,ih)\\,{0})", maxHeightParam));
}
}
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
index ba7b149508..c725326691 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
@@ -586,6 +586,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
return GetAvailableEncoder(mediaEncoder, "h264_omx", defaultEncoder);
}
+ if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(options.VaapiDevice))
+ {
+ return GetAvailableEncoder(mediaEncoder, "h264_vaapi", defaultEncoder);
+ }
}
return defaultEncoder;
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index f488be11a7..ad84ffee82 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -123,20 +123,20 @@ namespace MediaBrowser.MediaEncoding.Encoder
return "System";
}
- if (IsDefaultPath(FFMpegPath))
- {
- return "Default";
- }
-
return "Custom";
}
}
- private bool IsDefaultPath(string path)
+ public bool IsDefaultEncoderPath
{
- var parentPath = Path.Combine(ConfigurationManager.ApplicationPaths.ProgramDataPath, "ffmpeg", "20160410");
+ get
+ {
+ var path = FFMpegPath;
+
+ var parentPath = Path.Combine(ConfigurationManager.ApplicationPaths.ProgramDataPath, "ffmpeg", "20160410");
- return FileSystem.ContainsSubPath(parentPath, path);
+ return FileSystem.ContainsSubPath(parentPath, path);
+ }
}
private bool IsSystemInstalledPath(string path)
diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs
index 91d28a2969..3c03dc12a0 100644
--- a/MediaBrowser.Model/Configuration/EncodingOptions.cs
+++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs
@@ -10,6 +10,7 @@ namespace MediaBrowser.Model.Configuration
public int ThrottleDelaySeconds { get; set; }
public string HardwareAccelerationType { get; set; }
public string EncoderAppPath { get; set; }
+ public string VaapiDevice { get; set; }
public EncodingOptions()
{
@@ -17,6 +18,7 @@ namespace MediaBrowser.Model.Configuration
EnableThrottling = true;
ThrottleDelaySeconds = 180;
EncodingThreadCount = -1;
+ VaapiDevice = "/dev/dri/card0";
}
}
}
diff --git a/MediaBrowser.Model/Configuration/LibraryOptions.cs b/MediaBrowser.Model/Configuration/LibraryOptions.cs
index e15df37c1a..3fe694553a 100644
--- a/MediaBrowser.Model/Configuration/LibraryOptions.cs
+++ b/MediaBrowser.Model/Configuration/LibraryOptions.cs
@@ -4,10 +4,13 @@
{
public bool EnableArchiveMediaFiles { get; set; }
public bool EnablePhotos { get; set; }
+ public bool EnableRealtimeMonitor { get; set; }
+ public int SchemaVersion { get; set; }
public LibraryOptions()
{
EnablePhotos = true;
+ EnableRealtimeMonitor = true;
}
}
}
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index 63d452bcee..a891a422a5 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -74,6 +74,8 @@ namespace MediaBrowser.Model.Configuration
/// <value>The metadata path.</value>
public string MetadataPath { get; set; }
+ public string LastVersion { get; set; }
+
/// <summary>
/// Gets or sets the display name of the season zero.
/// </summary>
diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs
index 69dc23b21c..313c5243c3 100644
--- a/MediaBrowser.Model/Configuration/UserConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs
@@ -27,8 +27,6 @@ namespace MediaBrowser.Model.Configuration
public bool DisplayMissingEpisodes { get; set; }
public bool DisplayUnairedEpisodes { get; set; }
- public bool GroupMoviesIntoBoxSets { get; set; }
-
public string[] ExcludeFoldersFromGrouping { get; set; }
public string[] GroupedFolders { get; set; }
@@ -48,7 +46,6 @@ namespace MediaBrowser.Model.Configuration
public bool RememberAudioSelections { get; set; }
public bool RememberSubtitleSelections { get; set; }
public bool EnableNextEpisodeAutoPlay { get; set; }
- public bool DisplayFoldersView { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
diff --git a/MediaBrowser.Model/Dlna/AudioOptions.cs b/MediaBrowser.Model/Dlna/AudioOptions.cs
index c208e8ab0b..f3b6df861d 100644
--- a/MediaBrowser.Model/Dlna/AudioOptions.cs
+++ b/MediaBrowser.Model/Dlna/AudioOptions.cs
@@ -59,7 +59,7 @@ namespace MediaBrowser.Model.Dlna
/// Gets the maximum bitrate.
/// </summary>
/// <returns>System.Nullable&lt;System.Int32&gt;.</returns>
- public int? GetMaxBitrate()
+ public int? GetMaxBitrate(bool isAudio)
{
if (MaxBitrate.HasValue)
{
@@ -70,6 +70,10 @@ namespace MediaBrowser.Model.Dlna
{
if (Context == EncodingContext.Static)
{
+ if (isAudio && Profile.MaxStaticMusicBitrate.HasValue)
+ {
+ return Profile.MaxStaticMusicBitrate;
+ }
return Profile.MaxStaticBitrate;
}
diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs
index 423928f620..d6a3223227 100644
--- a/MediaBrowser.Model/Dlna/DeviceProfile.cs
+++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs
@@ -55,7 +55,7 @@ namespace MediaBrowser.Model.Dlna
public int? MaxStaticBitrate { get; set; }
public int? MusicStreamingTranscodingBitrate { get; set; }
- public int? MusicSyncBitrate { get; set; }
+ public int? MaxStaticMusicBitrate { get; set; }
/// <summary>
/// Controls the content of the X_DLNADOC element in the urn:schemas-dlna-org:device-1-0 namespace.
@@ -115,7 +115,6 @@ namespace MediaBrowser.Model.Dlna
MaxStreamingBitrate = 8000000;
MaxStaticBitrate = 8000000;
MusicStreamingTranscodingBitrate = 128000;
- MusicSyncBitrate = 128000;
}
public List<string> GetSupportedMediaTypes()
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 0710417c85..d042125b9b 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -55,7 +55,7 @@ namespace MediaBrowser.Model.Dlna
stream.DeviceProfileId = options.Profile.Id;
}
- return GetOptimalStream(streams, options.GetMaxBitrate());
+ return GetOptimalStream(streams, options.GetMaxBitrate(true));
}
public StreamInfo BuildVideoItem(VideoOptions options)
@@ -88,7 +88,7 @@ namespace MediaBrowser.Model.Dlna
stream.DeviceProfileId = options.Profile.Id;
}
- return GetOptimalStream(streams, options.GetMaxBitrate());
+ return GetOptimalStream(streams, options.GetMaxBitrate(false));
}
private StreamInfo GetOptimalStream(List<StreamInfo> streams, int? maxBitrate)
@@ -275,24 +275,32 @@ namespace MediaBrowser.Model.Dlna
playlistItem.MaxAudioChannels = Math.Min(options.MaxAudioChannels.Value, currentValue);
}
- int configuredBitrate = options.AudioTranscodingBitrate ??
- (options.Context == EncodingContext.Static ? options.Profile.MusicSyncBitrate : options.Profile.MusicStreamingTranscodingBitrate) ??
+ int transcodingBitrate = options.AudioTranscodingBitrate ??
+ options.Profile.MusicStreamingTranscodingBitrate ??
128000;
- playlistItem.AudioBitrate = Math.Min(configuredBitrate, playlistItem.AudioBitrate ?? configuredBitrate);
+ int? configuredBitrate = options.GetMaxBitrate(true);
+
+ if (configuredBitrate.HasValue)
+ {
+ transcodingBitrate = Math.Min(configuredBitrate.Value, transcodingBitrate);
+ }
+
+ playlistItem.AudioBitrate = Math.Min(transcodingBitrate, playlistItem.AudioBitrate ?? transcodingBitrate);
+
}
return playlistItem;
}
- private int? GetBitrateForDirectPlayCheck(MediaSourceInfo item, AudioOptions options)
+ private int? GetBitrateForDirectPlayCheck(MediaSourceInfo item, AudioOptions options, bool isAudio)
{
if (item.Protocol == MediaProtocol.File)
{
return options.Profile.MaxStaticBitrate;
}
- return options.GetMaxBitrate();
+ return options.GetMaxBitrate(isAudio);
}
private List<PlayMethod> GetAudioDirectPlayMethods(MediaSourceInfo item, MediaStream audioStream, AudioOptions options)
@@ -312,7 +320,7 @@ namespace MediaBrowser.Model.Dlna
if (directPlayProfile != null)
{
// While options takes the network and other factors into account. Only applies to direct stream
- if (item.SupportsDirectStream && IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate()) && options.EnableDirectStream)
+ if (item.SupportsDirectStream && IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate(true)) && options.EnableDirectStream)
{
playMethods.Add(PlayMethod.DirectStream);
}
@@ -320,7 +328,7 @@ namespace MediaBrowser.Model.Dlna
// The profile describes what the device supports
// If device requirements are satisfied then allow both direct stream and direct play
if (item.SupportsDirectPlay &&
- IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options)) && options.EnableDirectPlay)
+ IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true)) && options.EnableDirectPlay)
{
playMethods.Add(PlayMethod.DirectPlay);
}
@@ -403,8 +411,8 @@ namespace MediaBrowser.Model.Dlna
MediaStream videoStream = item.VideoStream;
// TODO: This doesn't accout for situation of device being able to handle media bitrate, but wifi connection not fast enough
- bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options), subtitleStream, options, PlayMethod.DirectPlay));
- bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || IsEligibleForDirectPlay(item, options.GetMaxBitrate(), subtitleStream, options, PlayMethod.DirectStream));
+ bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true), subtitleStream, options, PlayMethod.DirectPlay));
+ bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || IsEligibleForDirectPlay(item, options.GetMaxBitrate(false), subtitleStream, options, PlayMethod.DirectStream));
_logger.Info("Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}",
options.Profile.Name ?? "Unknown Profile",
@@ -469,7 +477,6 @@ namespace MediaBrowser.Model.Dlna
playlistItem.VideoCodec = transcodingProfile.VideoCodec;
playlistItem.CopyTimestamps = transcodingProfile.CopyTimestamps;
- playlistItem.ForceLiveStream = transcodingProfile.ForceLiveStream;
playlistItem.EnableSubtitlesInManifest = transcodingProfile.EnableSubtitlesInManifest;
if (!string.IsNullOrEmpty(transcodingProfile.MaxAudioChannels))
@@ -570,10 +577,10 @@ namespace MediaBrowser.Model.Dlna
playlistItem.MaxAudioChannels = Math.Min(options.MaxAudioChannels.Value, currentValue);
}
- int audioBitrate = GetAudioBitrate(playlistItem.SubProtocol, options.GetMaxBitrate(), playlistItem.TargetAudioChannels, playlistItem.TargetAudioCodec, audioStream);
+ int audioBitrate = GetAudioBitrate(playlistItem.SubProtocol, options.GetMaxBitrate(false), playlistItem.TargetAudioChannels, playlistItem.TargetAudioCodec, audioStream);
playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate);
- int? maxBitrateSetting = options.GetMaxBitrate();
+ int? maxBitrateSetting = options.GetMaxBitrate(false);
// Honor max rate
if (maxBitrateSetting.HasValue)
{
@@ -595,19 +602,16 @@ namespace MediaBrowser.Model.Dlna
private int GetAudioBitrate(string subProtocol, int? maxTotalBitrate, int? targetAudioChannels, string targetAudioCodec, MediaStream audioStream)
{
- var defaultBitrate = 128000;
- if (StringHelper.EqualsIgnoreCase(targetAudioCodec, "ac3"))
- {
- defaultBitrate = 192000;
- }
- if (!string.IsNullOrEmpty(targetAudioCodec) && audioStream != null && StringHelper.EqualsIgnoreCase(audioStream.Codec, targetAudioCodec))
+ var defaultBitrate = audioStream.BitRate ?? 192000;
+ // Reduce the bitrate if we're downmixing
+ if (targetAudioChannels.HasValue && audioStream != null && audioStream.Channels.HasValue && targetAudioChannels.Value < audioStream.Channels.Value)
{
- defaultBitrate = audioStream.BitRate ?? defaultBitrate;
+ defaultBitrate = StringHelper.EqualsIgnoreCase(targetAudioCodec, "ac3") ? 192000 : 128000;
}
if (targetAudioChannels.HasValue)
{
- if (targetAudioChannels.Value >= 5 && (maxTotalBitrate ?? 0) >= 1500000)
+ if (targetAudioChannels.Value >= 5 && (maxTotalBitrate ?? 0) >= 1200000)
{
if (StringHelper.EqualsIgnoreCase(targetAudioCodec, "ac3"))
{
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index 02239aa484..ac024f00b9 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -36,7 +36,6 @@ namespace MediaBrowser.Model.Dlna
public string VideoProfile { get; set; }
public bool CopyTimestamps { get; set; }
- public bool ForceLiveStream { get; set; }
public bool EnableSubtitlesInManifest { get; set; }
public string[] AudioCodecs { get; set; }
@@ -216,7 +215,7 @@ namespace MediaBrowser.Model.Dlna
list.Add(new NameValuePair("MaxWidth", item.MaxWidth.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxWidth.Value) : string.Empty));
list.Add(new NameValuePair("MaxHeight", item.MaxHeight.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxHeight.Value) : string.Empty));
- if (StringHelper.EqualsIgnoreCase(item.SubProtocol, "hls") && !item.ForceLiveStream)
+ if (StringHelper.EqualsIgnoreCase(item.SubProtocol, "hls"))
{
list.Add(new NameValuePair("StartTimeTicks", string.Empty));
}
@@ -246,7 +245,6 @@ namespace MediaBrowser.Model.Dlna
}
list.Add(new NameValuePair("CopyTimestamps", item.CopyTimestamps.ToString().ToLower()));
- list.Add(new NameValuePair("ForceLiveStream", item.ForceLiveStream.ToString().ToLower()));
list.Add(new NameValuePair("SubtitleMethod", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External ? item.SubtitleDeliveryMethod.ToString() : string.Empty));
list.Add(new NameValuePair("TranscodingMaxAudioChannels", item.TranscodingMaxAudioChannels.HasValue ? StringHelper.ToStringCultureInvariant(item.TranscodingMaxAudioChannels.Value) : string.Empty));
diff --git a/MediaBrowser.Model/Dlna/TranscodingProfile.cs b/MediaBrowser.Model/Dlna/TranscodingProfile.cs
index 19caf85eb2..beb83b053b 100644
--- a/MediaBrowser.Model/Dlna/TranscodingProfile.cs
+++ b/MediaBrowser.Model/Dlna/TranscodingProfile.cs
@@ -35,9 +35,6 @@ namespace MediaBrowser.Model.Dlna
[XmlAttribute("context")]
public EncodingContext Context { get; set; }
- [XmlAttribute("forceLiveStream")]
- public bool ForceLiveStream { get; set; }
-
[XmlAttribute("enableSubtitlesInManifest")]
public bool EnableSubtitlesInManifest { get; set; }
diff --git a/MediaBrowser.Model/Entities/MetadataProviders.cs b/MediaBrowser.Model/Entities/MetadataProviders.cs
index f5ab0c1d47..1e7bde934d 100644
--- a/MediaBrowser.Model/Entities/MetadataProviders.cs
+++ b/MediaBrowser.Model/Entities/MetadataProviders.cs
@@ -39,6 +39,7 @@ namespace MediaBrowser.Model.Entities
TvRage = 15,
AudioDbArtist = 16,
AudioDbAlbum = 17,
- MusicBrainzTrack = 18
+ MusicBrainzTrack = 18,
+ TvMaze = 19
}
}
diff --git a/MediaBrowser.Model/FileOrganization/FileOrganizationResult.cs b/MediaBrowser.Model/FileOrganization/FileOrganizationResult.cs
index ef9d0ca2ae..caf99183dc 100644
--- a/MediaBrowser.Model/FileOrganization/FileOrganizationResult.cs
+++ b/MediaBrowser.Model/FileOrganization/FileOrganizationResult.cs
@@ -95,6 +95,12 @@ namespace MediaBrowser.Model.FileOrganization
/// <value>The size of the file.</value>
public long FileSize { get; set; }
+ /// <summary>
+ /// Indicates if the item is currently being processed.
+ /// </summary>
+ /// <remarks>Runtime property not persisted to the store.</remarks>
+ public bool IsInProgress { get; set; }
+
public FileOrganizationResult()
{
DuplicatePaths = new List<string>();
diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs
index a138145381..8bf0703be9 100644
--- a/MediaBrowser.Model/Net/MimeTypes.cs
+++ b/MediaBrowser.Model/Net/MimeTypes.cs
@@ -241,7 +241,7 @@ namespace MediaBrowser.Model.Net
}
if (StringHelper.EqualsIgnoreCase(ext, ".opus"))
{
- return "audio/opus";
+ return "audio/ogg";
}
// Playlists
diff --git a/MediaBrowser.Model/Querying/ItemFilter.cs b/MediaBrowser.Model/Querying/ItemFilter.cs
index 83d61ae514..ff28bd08c4 100644
--- a/MediaBrowser.Model/Querying/ItemFilter.cs
+++ b/MediaBrowser.Model/Querying/ItemFilter.cs
@@ -27,10 +27,6 @@ namespace MediaBrowser.Model.Querying
/// </summary>
IsFavorite = 5,
/// <summary>
- /// The is recently added
- /// </summary>
- IsRecentlyAdded = 6,
- /// <summary>
/// The item is resumable
/// </summary>
IsResumable = 7,
diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
index 6c79189887..027341ee6a 100644
--- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
@@ -167,10 +167,13 @@ namespace MediaBrowser.Providers.MediaInfo
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
{
- var file = directoryService.GetFile(item.Path);
- if (file != null && file.LastWriteTimeUtc != item.DateModified)
+ if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem)
{
- return true;
+ var file = directoryService.GetFile(item.Path);
+ if (file != null && file.LastWriteTimeUtc != item.DateModified)
+ {
+ return true;
+ }
}
return false;
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
index 0df8b6c4b7..d255110fb7 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
@@ -171,7 +171,7 @@ namespace MediaBrowser.Providers.MediaInfo
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
{
- if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path))
+ if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem)
{
var file = directoryService.GetFile(item.Path);
if (file != null && file.LastWriteTimeUtc != item.DateModified)
diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
index 280e92beb9..2ad02da2ef 100644
--- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
@@ -194,7 +194,7 @@ namespace MediaBrowser.Providers.MediaInfo
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
{
- if (item.EnableRefreshOnDateModifiedChange)
+ if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem)
{
var file = directoryService.GetFile(item.Path);
if (file != null && file.LastWriteTimeUtc != item.DateModified)
diff --git a/MediaBrowser.Providers/Photos/PhotoProvider.cs b/MediaBrowser.Providers/Photos/PhotoProvider.cs
index 619b726368..c48c3d09be 100644
--- a/MediaBrowser.Providers/Photos/PhotoProvider.cs
+++ b/MediaBrowser.Providers/Photos/PhotoProvider.cs
@@ -154,10 +154,13 @@ namespace MediaBrowser.Providers.Photos
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
{
- var file = directoryService.GetFile(item.Path);
- if (file != null && file.LastWriteTimeUtc != item.DateModified)
+ if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem)
{
- return true;
+ var file = directoryService.GetFile(item.Path);
+ if (file != null && file.LastWriteTimeUtc != item.DateModified)
+ {
+ return true;
+ }
}
return false;
diff --git a/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs
index 620eea774e..414fda400b 100644
--- a/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs
+++ b/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs
@@ -54,18 +54,15 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
private async void SendMessage(string name, TimerEventInfo info)
{
- var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).ToList();
+ var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).Select(i => i.Id.ToString("N")).ToList();
- foreach (var user in users)
+ try
{
- try
- {
- await _sessionManager.SendMessageToUserSessions<TimerEventInfo>(user.Id.ToString("N"), name, info, CancellationToken.None);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error sending message", ex);
- }
+ await _sessionManager.SendMessageToUserSessions<TimerEventInfo>(users, name, info, CancellationToken.None);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error sending message", ex);
}
}
diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs
index b5624625f2..3ea8417f86 100644
--- a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs
+++ b/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs
@@ -11,6 +11,7 @@ using MediaBrowser.Controller.Sync;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Sync;
using System;
+using System.Collections.Generic;
using System.Threading;
namespace MediaBrowser.Server.Implementations.EntryPoints
@@ -164,7 +165,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
private async void SendMessageToUserSession<T>(User user, string name, T data)
{
- await _sessionManager.SendMessageToUserSessions(user.Id.ToString("N"), name, data, CancellationToken.None);
+ await _sessionManager.SendMessageToUserSessions(new List<string> { user.Id.ToString("N") }, name, data, CancellationToken.None);
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
index 39992b65dd..5e01666a9a 100644
--- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
+++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
@@ -272,6 +272,18 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
var originalExtractedSeriesString = result.ExtractedName;
+ bool isNew = string.IsNullOrWhiteSpace(result.Id);
+
+ if (isNew)
+ {
+ await _organizationService.SaveResult(result, cancellationToken);
+ }
+
+ if (!_organizationService.AddToInProgressList(result, isNew))
+ {
+ throw new Exception("File is currently processed otherwise. Please try again later.");
+ }
+
try
{
// Proceed to sort the file
@@ -363,6 +375,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
_logger.Warn(ex.Message);
return;
}
+ finally
+ {
+ _organizationService.RemoveFromInprogressList(result);
+ }
if (rememberCorrection)
{
diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs
new file mode 100644
index 0000000000..38b90647c1
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs
@@ -0,0 +1,68 @@
+using MediaBrowser.Controller.FileOrganization;
+using MediaBrowser.Controller.Plugins;
+using MediaBrowser.Model.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.FileOrganization;
+using MediaBrowser.Controller.Session;
+using System.Threading;
+
+namespace MediaBrowser.Server.Implementations.FileOrganization
+{
+ /// <summary>
+ /// Class SessionInfoWebSocketListener
+ /// </summary>
+ class FileOrganizationNotifier : IServerEntryPoint
+ {
+ private readonly IFileOrganizationService _organizationService;
+ private readonly ISessionManager _sessionManager;
+
+ public FileOrganizationNotifier(ILogger logger, IFileOrganizationService organizationService, ISessionManager sessionManager)
+ {
+ _organizationService = organizationService;
+ _sessionManager = sessionManager;
+ }
+
+ public void Run()
+ {
+ _organizationService.ItemAdded += _organizationService_ItemAdded;
+ _organizationService.ItemRemoved += _organizationService_ItemRemoved;
+ _organizationService.ItemUpdated += _organizationService_ItemUpdated;
+ _organizationService.LogReset += _organizationService_LogReset;
+ }
+
+ private void _organizationService_LogReset(object sender, EventArgs e)
+ {
+ _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None);
+ }
+
+ private void _organizationService_ItemUpdated(object sender, GenericEventArgs<FileOrganizationResult> e)
+ {
+ _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", e.Argument, CancellationToken.None);
+ }
+
+ private void _organizationService_ItemRemoved(object sender, GenericEventArgs<FileOrganizationResult> e)
+ {
+ _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None);
+ }
+
+ private void _organizationService_ItemAdded(object sender, GenericEventArgs<FileOrganizationResult> e)
+ {
+ _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None);
+ }
+
+ public void Dispose()
+ {
+ _organizationService.ItemAdded -= _organizationService_ItemAdded;
+ _organizationService.ItemRemoved -= _organizationService_ItemRemoved;
+ _organizationService.ItemUpdated -= _organizationService_ItemUpdated;
+ _organizationService.LogReset -= _organizationService_LogReset;
+ }
+
+
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs
index 9e16613e62..a42eba6cae 100644
--- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs
+++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs
@@ -3,16 +3,21 @@ using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.FileOrganization;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.FileOrganization;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
using System;
+using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Controller.Session;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Common.Events;
namespace MediaBrowser.Server.Implementations.FileOrganization
{
@@ -26,6 +31,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
private readonly IServerConfigurationManager _config;
private readonly IFileSystem _fileSystem;
private readonly IProviderManager _providerManager;
+ private readonly ConcurrentDictionary<string, bool> _inProgressItemIds = new ConcurrentDictionary<string, bool>();
+
+ public event EventHandler<GenericEventArgs<FileOrganizationResult>> ItemAdded;
+ public event EventHandler<GenericEventArgs<FileOrganizationResult>> ItemUpdated;
+ public event EventHandler<GenericEventArgs<FileOrganizationResult>> ItemRemoved;
+ public event EventHandler LogReset;
public FileOrganizationService(ITaskManager taskManager, IFileOrganizationRepository repo, ILogger logger, ILibraryMonitor libraryMonitor, ILibraryManager libraryManager, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager)
{
@@ -58,12 +69,26 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
public QueryResult<FileOrganizationResult> GetResults(FileOrganizationResultQuery query)
{
- return _repo.GetResults(query);
+ var results = _repo.GetResults(query);
+
+ foreach (var result in results.Items)
+ {
+ result.IsInProgress = _inProgressItemIds.ContainsKey(result.Id);
+ }
+
+ return results;
}
public FileOrganizationResult GetResult(string id)
{
- return _repo.GetResult(id);
+ var result = _repo.GetResult(id);
+
+ if (result != null)
+ {
+ result.IsInProgress = _inProgressItemIds.ContainsKey(result.Id);
+ }
+
+ return result;
}
public FileOrganizationResult GetResultBySourcePath(string path)
@@ -78,11 +103,17 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
return GetResult(id);
}
- public Task DeleteOriginalFile(string resultId)
+ public async Task DeleteOriginalFile(string resultId)
{
var result = _repo.GetResult(resultId);
_logger.Info("Requested to delete {0}", result.OriginalPath);
+
+ if (!AddToInProgressList(result, false))
+ {
+ throw new Exception("Path is currently processed otherwise. Please try again later.");
+ }
+
try
{
_fileSystem.DeleteFile(result.OriginalPath);
@@ -91,8 +122,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
{
_logger.ErrorException("Error deleting {0}", ex, result.OriginalPath);
}
+ finally
+ {
+ RemoveFromInprogressList(result);
+ }
- return _repo.Delete(resultId);
+ await _repo.Delete(resultId);
+
+ EventHelper.FireEventIfNotNull(ItemRemoved, this, new GenericEventArgs<FileOrganizationResult>(result), _logger);
}
private AutoOrganizeOptions GetAutoOrganizeOptions()
@@ -121,9 +158,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
}
}
- public Task ClearLog()
+ public async Task ClearLog()
{
- return _repo.DeleteAll();
+ await _repo.DeleteAll();
+ EventHelper.FireEventIfNotNull(LogReset, this, EventArgs.Empty, _logger);
}
public async Task PerformEpisodeOrganization(EpisodeFileOrganizationRequest request)
@@ -189,5 +227,55 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
_config.SaveAutoOrganizeOptions(options);
}
}
+
+ /// <summary>
+ /// Attempts to add a an item to the list of currently processed items.
+ /// </summary>
+ /// <param name="result">The result item.</param>
+ /// <param name="isNewItem">Passing true will notify the client to reload all items, otherwise only a single item will be refreshed.</param>
+ /// <returns>True if the item was added, False if the item is already contained in the list.</returns>
+ public bool AddToInProgressList(FileOrganizationResult result, bool isNewItem)
+ {
+ if (string.IsNullOrWhiteSpace(result.Id))
+ {
+ result.Id = result.OriginalPath.GetMD5().ToString("N");
+ }
+
+ if (!_inProgressItemIds.TryAdd(result.Id, false))
+ {
+ return false;
+ }
+
+ result.IsInProgress = true;
+
+ if (isNewItem)
+ {
+ EventHelper.FireEventIfNotNull(ItemAdded, this, new GenericEventArgs<FileOrganizationResult>(result), _logger);
+ }
+ else
+ {
+ EventHelper.FireEventIfNotNull(ItemUpdated, this, new GenericEventArgs<FileOrganizationResult>(result), _logger);
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// Removes an item from the list of currently processed items.
+ /// </summary>
+ /// <param name="result">The result item.</param>
+ /// <returns>True if the item was removed, False if the item was not contained in the list.</returns>
+ public bool RemoveFromInprogressList(FileOrganizationResult result)
+ {
+ bool itemValue;
+ var retval = _inProgressItemIds.TryRemove(result.Id, out itemValue);
+
+ result.IsInProgress = false;
+
+ EventHelper.FireEventIfNotNull(ItemUpdated, this, new GenericEventArgs<FileOrganizationResult>(result), _logger);
+
+ return retval;
+ }
+
}
}
diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
index 6332087391..51a53fe211 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -428,8 +428,24 @@ namespace MediaBrowser.Server.Implementations.HttpServer
if (string.Equals(localPath, "/mediabrowser/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(localPath, "/mediabrowser", StringComparison.OrdinalIgnoreCase) ||
- localPath.IndexOf("mediabrowser/web", StringComparison.OrdinalIgnoreCase) != -1 ||
- localPath.IndexOf("dashboard/", StringComparison.OrdinalIgnoreCase) != -1)
+ localPath.IndexOf("mediabrowser/web", StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ httpRes.StatusCode = 200;
+ httpRes.ContentType = "text/html";
+ var newUrl = urlString.Replace("mediabrowser", "emby", StringComparison.OrdinalIgnoreCase)
+ .Replace("/dashboard/", "/web/", StringComparison.OrdinalIgnoreCase);
+
+ if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase))
+ {
+ httpRes.Write("<!doctype html><html><head><title>Emby</title></head><body>Please update your Emby bookmark to <a href=\"" + newUrl + "\">" + newUrl + "</a></body></html>");
+
+ httpRes.Close();
+ return;
+ }
+ }
+
+ if (localPath.IndexOf("dashboard/", StringComparison.OrdinalIgnoreCase) != -1 &&
+ localPath.IndexOf("web/dashboard", StringComparison.OrdinalIgnoreCase) == -1)
{
httpRes.StatusCode = 200;
httpRes.ContentType = "text/html";
diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
index ea9e58ee47..7ed4dc71ef 100644
--- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
+++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
@@ -172,27 +172,29 @@ namespace MediaBrowser.Server.Implementations.IO
}
}
- public void Start()
+ private bool IsLibraryMonitorEnabaled(BaseItem item)
{
- if (EnableLibraryMonitor)
+ var options = LibraryManager.GetLibraryOptions(item);
+
+ if (options != null && options.SchemaVersion >= 1)
{
- StartInternal();
+ return options.EnableRealtimeMonitor;
}
+
+ return EnableLibraryMonitor;
}
- /// <summary>
- /// Starts this instance.
- /// </summary>
- private void StartInternal()
+ public void Start()
{
LibraryManager.ItemAdded += LibraryManager_ItemAdded;
LibraryManager.ItemRemoved += LibraryManager_ItemRemoved;
- var pathsToWatch = new List<string> { LibraryManager.RootFolder.Path };
+ var pathsToWatch = new List<string> { };
var paths = LibraryManager
.RootFolder
.Children
+ .Where(IsLibraryMonitorEnabaled)
.OfType<Folder>()
.SelectMany(f => f.PhysicalLocations)
.Distinct(StringComparer.OrdinalIgnoreCase)
@@ -213,6 +215,14 @@ namespace MediaBrowser.Server.Implementations.IO
}
}
+ private void StartWatching(BaseItem item)
+ {
+ if (IsLibraryMonitorEnabaled(item))
+ {
+ StartWatchingPath(item.Path);
+ }
+ }
+
/// <summary>
/// Handles the ItemRemoved event of the LibraryManager control.
/// </summary>
@@ -235,7 +245,7 @@ namespace MediaBrowser.Server.Implementations.IO
{
if (e.Item.GetParent() is AggregateFolder)
{
- StartWatchingPath(e.Item.Path);
+ StartWatching(e.Item);
}
}
@@ -382,14 +392,6 @@ namespace MediaBrowser.Server.Implementations.IO
Logger.ErrorException("Error in Directory watcher for: " + dw.Path, ex);
DisposeWatcher(dw);
-
- if (ConfigurationManager.Configuration.EnableLibraryMonitor == AutoOnOff.Auto)
- {
- Logger.Info("Disabling realtime monitor to prevent future instability");
-
- ConfigurationManager.Configuration.EnableLibraryMonitor = AutoOnOff.Disabled;
- Stop();
- }
}
/// <summary>
@@ -420,8 +422,8 @@ namespace MediaBrowser.Server.Implementations.IO
var filename = Path.GetFileName(path);
- var monitorPath = !string.IsNullOrEmpty(filename) &&
- !_alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase) &&
+ var monitorPath = !string.IsNullOrEmpty(filename) &&
+ !_alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase) &&
!_alwaysIgnoreExtensions.Contains(Path.GetExtension(path) ?? string.Empty, StringComparer.OrdinalIgnoreCase);
// Ignore certain files
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 6558407538..ee9533d2ac 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -203,12 +203,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
/// <returns>Video.</returns>
protected override Video Resolve(ItemResolveArgs args)
{
- if (args.Path != null && args.Path.IndexOf("disney", StringComparison.OrdinalIgnoreCase) != -1)
- {
- var b = true;
- var a = b;
- }
-
var collectionType = args.GetCollectionType();
if (IsInvalid(args.Parent, collectionType))
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index 7fa9ee32c2..6879c3f407 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -149,6 +149,7 @@
<Compile Include="EntryPoints\UsageReporter.cs" />
<Compile Include="FileOrganization\EpisodeFileOrganizer.cs" />
<Compile Include="FileOrganization\Extensions.cs" />
+ <Compile Include="FileOrganization\FileOrganizationNotifier.cs" />
<Compile Include="FileOrganization\FileOrganizationService.cs" />
<Compile Include="FileOrganization\NameUtils.cs" />
<Compile Include="FileOrganization\TvFolderOrganizer.cs" />
@@ -271,6 +272,7 @@
<Compile Include="Sorting\StartDateComparer.cs" />
<Compile Include="Sync\SyncHelper.cs" />
<Compile Include="Sync\SyncJobOptions.cs" />
+ <Compile Include="Sync\SyncNotificationEntryPoint.cs" />
<Compile Include="UserViews\CollectionFolderImageProvider.cs" />
<Compile Include="UserViews\DynamicImageProvider.cs" />
<Compile Include="News\NewsEntryPoint.cs" />
diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs
index 7f709d084f..46ba7d2e74 100644
--- a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs
+++ b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs
@@ -123,7 +123,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
{
if (extractImages)
{
- if (video.VideoType == VideoType.HdDvd || video.VideoType == VideoType.Iso || video.VideoType == VideoType.BluRay)
+ if (video.VideoType == VideoType.HdDvd || video.VideoType == VideoType.Iso || video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd)
{
continue;
}
diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
index bf2afb5ace..c1394ee1c3 100644
--- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
@@ -313,8 +313,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
if (Folder.IsPathOffline(path))
{
- libraryItem.IsOffline = true;
- await libraryItem.UpdateToRepository(ItemUpdateType.None, cancellationToken).ConfigureAwait(false);
+ await libraryItem.UpdateIsOffline(true).ConfigureAwait(false);
continue;
}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index c3eee6d354..5c94d589dc 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -211,7 +211,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
_connection.AddColumn(Logger, "TypedBaseItems", "ProductionYear", "INT");
_connection.AddColumn(Logger, "TypedBaseItems", "ParentId", "GUID");
_connection.AddColumn(Logger, "TypedBaseItems", "Genres", "Text");
- _connection.AddColumn(Logger, "TypedBaseItems", "ParentalRatingValue", "INT");
_connection.AddColumn(Logger, "TypedBaseItems", "SchemaVersion", "INT");
_connection.AddColumn(Logger, "TypedBaseItems", "SortName", "Text");
_connection.AddColumn(Logger, "TypedBaseItems", "RunTimeTicks", "BIGINT");
@@ -488,7 +487,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
"ProductionYear",
"ParentId",
"Genres",
- "ParentalRatingValue",
"InheritedParentalRatingValue",
"SchemaVersion",
"SortName",
@@ -795,7 +793,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
_saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Genres.ToArray());
- _saveItemCommand.GetParameter(index++).Value = item.GetParentalRatingValue() ?? 0;
_saveItemCommand.GetParameter(index++).Value = item.GetInheritedParentalRatingValue() ?? 0;
_saveItemCommand.GetParameter(index++).Value = LatestSchemaVersion;
@@ -4286,6 +4283,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
var index = 0;
foreach (var image in images)
{
+ if (string.IsNullOrWhiteSpace(image.Path))
+ {
+ // Invalid
+ continue;
+ }
+
_saveImagesCommand.GetParameter(0).Value = itemId;
_saveImagesCommand.GetParameter(1).Value = image.Type;
_saveImagesCommand.GetParameter(2).Value = image.Path;
diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
index f495e557a3..b21fcddd41 100644
--- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs
+++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
@@ -1869,10 +1869,17 @@ namespace MediaBrowser.Server.Implementations.Session
return GetSessionByAuthenticationToken(info, deviceId, remoteEndpoint, null);
}
- public Task SendMessageToUserSessions<T>(string userId, string name, T data,
+ public Task SendMessageToAdminSessions<T>(string name, T data, CancellationToken cancellationToken)
+ {
+ var adminUserIds = _userManager.Users.Where(i => i.Policy.IsAdministrator).Select(i => i.Id.ToString("N")).ToList();
+
+ return SendMessageToUserSessions(adminUserIds, name, data, cancellationToken);
+ }
+
+ public Task SendMessageToUserSessions<T>(List<string> userIds, string name, T data,
CancellationToken cancellationToken)
{
- var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null && i.ContainsUser(userId)).ToList();
+ var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null && userIds.Any(i.ContainsUser)).ToList();
var tasks = sessions.Select(session => Task.Run(async () =>
{
diff --git a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs
index 03485012f0..408ec717eb 100644
--- a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs
+++ b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs
@@ -85,6 +85,11 @@ namespace MediaBrowser.Server.Implementations.Sync
{
Name = "Low",
Id = "low"
+ },
+ new SyncQualityOption
+ {
+ Name = "Custom",
+ Id = "custom"
}
};
}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncNotificationEntryPoint.cs b/MediaBrowser.Server.Implementations/Sync/SyncNotificationEntryPoint.cs
new file mode 100644
index 0000000000..7017b422ee
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Sync/SyncNotificationEntryPoint.cs
@@ -0,0 +1,48 @@
+using System.Threading;
+using MediaBrowser.Controller.Plugins;
+using MediaBrowser.Controller.Session;
+using MediaBrowser.Controller.Sync;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Sync;
+
+namespace MediaBrowser.Server.Implementations.Sync
+{
+ public class SyncNotificationEntryPoint : IServerEntryPoint
+ {
+ private readonly ISessionManager _sessionManager;
+ private readonly ISyncManager _syncManager;
+
+ public SyncNotificationEntryPoint(ISyncManager syncManager, ISessionManager sessionManager)
+ {
+ _syncManager = syncManager;
+ _sessionManager = sessionManager;
+ }
+
+ public void Run()
+ {
+ _syncManager.SyncJobItemUpdated += _syncManager_SyncJobItemUpdated;
+ }
+
+ private async void _syncManager_SyncJobItemUpdated(object sender, GenericEventArgs<SyncJobItem> e)
+ {
+ var item = e.Argument;
+
+ if (item.Status == SyncJobItemStatus.ReadyToTransfer)
+ {
+ try
+ {
+ await _sessionManager.SendMessageToUserDeviceSessions(item.TargetId, "SyncJobItemReady", item, CancellationToken.None).ConfigureAwait(false);
+ }
+ catch
+ {
+
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ _syncManager.SyncJobItemUpdated -= _syncManager_SyncJobItemUpdated;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj
index 104923f8ee..f04b833b90 100644
--- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj
+++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj
@@ -390,6 +390,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\autoorganizetv.html">
<Link>Resources\dashboard-ui\autoorganizetv.html</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\camerauploadsettings.html">
+ <Link>Resources\dashboard-ui\camerauploadsettings.html</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\channelitems.html">
<Link>Resources\dashboard-ui\channelitems.html</Link>
</BundleResource>
@@ -1128,9 +1131,6 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\multidownload.js">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\multidownload.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\objectassign.js">
- <Link>Resources\dashboard-ui\bower_components\emby-webcomponents\objectassign.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\playmenu.js">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\playmenu.js</Link>
</BundleResource>
@@ -1155,6 +1155,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\shortcuts.js">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\shortcuts.js</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\thememediaplayer.js">
+ <Link>Resources\dashboard-ui\bower_components\emby-webcomponents\thememediaplayer.js</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\visibleinviewport.js">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\visibleinviewport.js</Link>
</BundleResource>
@@ -1566,6 +1569,15 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\playlisteditor\playlisteditor.js">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\playlisteditor\playlisteditor.js</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\polyfills\array.js">
+ <Link>Resources\dashboard-ui\bower_components\emby-webcomponents\polyfills\array.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\polyfills\bind.js">
+ <Link>Resources\dashboard-ui\bower_components\emby-webcomponents\polyfills\bind.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\polyfills\objectassign.js">
+ <Link>Resources\dashboard-ui\bower_components\emby-webcomponents\polyfills\objectassign.js</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\prompt\nativeprompt.js">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\prompt\nativeprompt.js</Link>
</BundleResource>
@@ -1773,6 +1785,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\subtitleeditor\subtitleeditor.template.html">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\subtitleeditor\subtitleeditor.template.html</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\sync\sync.js">
+ <Link>Resources\dashboard-ui\bower_components\emby-webcomponents\sync\sync.js</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\toast\toast.css">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\toast\toast.css</Link>
</BundleResource>
@@ -1860,36 +1875,6 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\fetch\fetch.js">
<Link>Resources\dashboard-ui\bower_components\fetch\fetch.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\fingerprintjs2\.bower.json">
- <Link>Resources\dashboard-ui\bower_components\fingerprintjs2\.bower.json</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\fingerprintjs2\CONTRIBUTING.md">
- <Link>Resources\dashboard-ui\bower_components\fingerprintjs2\CONTRIBUTING.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\fingerprintjs2\FAQ.md">
- <Link>Resources\dashboard-ui\bower_components\fingerprintjs2\FAQ.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\fingerprintjs2\README.md">
- <Link>Resources\dashboard-ui\bower_components\fingerprintjs2\README.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\fingerprintjs2\bower.json">
- <Link>Resources\dashboard-ui\bower_components\fingerprintjs2\bower.json</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\fingerprintjs2\fingerprint2.js">
- <Link>Resources\dashboard-ui\bower_components\fingerprintjs2\fingerprint2.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\fingerprintjs2\gulpfile.js">
- <Link>Resources\dashboard-ui\bower_components\fingerprintjs2\gulpfile.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\fingerprintjs2\index.html">
- <Link>Resources\dashboard-ui\bower_components\fingerprintjs2\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\fingerprintjs2\package.json">
- <Link>Resources\dashboard-ui\bower_components\fingerprintjs2\package.json</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\fingerprintjs2\dist\fingerprint2.min.js">
- <Link>Resources\dashboard-ui\bower_components\fingerprintjs2\dist\fingerprint2.min.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\font-roboto\.bower.json">
<Link>Resources\dashboard-ui\bower_components\font-roboto\.bower.json</Link>
</BundleResource>
@@ -2094,45 +2079,6 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-a11y-keys-behavior\test\index.html">
<Link>Resources\dashboard-ui\bower_components\iron-a11y-keys-behavior\test\index.html</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-autogrow-textarea\.bower.json">
- <Link>Resources\dashboard-ui\bower_components\iron-autogrow-textarea\.bower.json</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-autogrow-textarea\.gitignore">
- <Link>Resources\dashboard-ui\bower_components\iron-autogrow-textarea\.gitignore</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-autogrow-textarea\.travis.yml">
- <Link>Resources\dashboard-ui\bower_components\iron-autogrow-textarea\.travis.yml</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-autogrow-textarea\CONTRIBUTING.md">
- <Link>Resources\dashboard-ui\bower_components\iron-autogrow-textarea\CONTRIBUTING.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-autogrow-textarea\README.md">
- <Link>Resources\dashboard-ui\bower_components\iron-autogrow-textarea\README.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-autogrow-textarea\bower.json">
- <Link>Resources\dashboard-ui\bower_components\iron-autogrow-textarea\bower.json</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-autogrow-textarea\hero.svg">
- <Link>Resources\dashboard-ui\bower_components\iron-autogrow-textarea\hero.svg</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-autogrow-textarea\index.html">
- <Link>Resources\dashboard-ui\bower_components\iron-autogrow-textarea\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-autogrow-textarea\iron-autogrow-textarea.html">
- <Link>Resources\dashboard-ui\bower_components\iron-autogrow-textarea\iron-autogrow-textarea.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-autogrow-textarea\.github\ISSUE_TEMPLATE.md">
- <Link>Resources\dashboard-ui\bower_components\iron-autogrow-textarea\.github\ISSUE_TEMPLATE.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-autogrow-textarea\demo\index.html">
- <Link>Resources\dashboard-ui\bower_components\iron-autogrow-textarea\demo\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-autogrow-textarea\test\basic.html">
- <Link>Resources\dashboard-ui\bower_components\iron-autogrow-textarea\test\basic.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-autogrow-textarea\test\index.html">
- <Link>Resources\dashboard-ui\bower_components\iron-autogrow-textarea\test\index.html</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-behaviors\.bower.json">
<Link>Resources\dashboard-ui\bower_components\iron-behaviors\.bower.json</Link>
</BundleResource>
@@ -2502,51 +2448,6 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-iconset-svg\test\iron-iconset-svg.html">
<Link>Resources\dashboard-ui\bower_components\iron-iconset-svg\test\iron-iconset-svg.html</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\.bower.json">
- <Link>Resources\dashboard-ui\bower_components\iron-input\.bower.json</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\.gitignore">
- <Link>Resources\dashboard-ui\bower_components\iron-input\.gitignore</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\.travis.yml">
- <Link>Resources\dashboard-ui\bower_components\iron-input\.travis.yml</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\CONTRIBUTING.md">
- <Link>Resources\dashboard-ui\bower_components\iron-input\CONTRIBUTING.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\README.md">
- <Link>Resources\dashboard-ui\bower_components\iron-input\README.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\bower.json">
- <Link>Resources\dashboard-ui\bower_components\iron-input\bower.json</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\hero.svg">
- <Link>Resources\dashboard-ui\bower_components\iron-input\hero.svg</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\index.html">
- <Link>Resources\dashboard-ui\bower_components\iron-input\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\iron-input.html">
- <Link>Resources\dashboard-ui\bower_components\iron-input\iron-input.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\.github\ISSUE_TEMPLATE.md">
- <Link>Resources\dashboard-ui\bower_components\iron-input\.github\ISSUE_TEMPLATE.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\demo\index.html">
- <Link>Resources\dashboard-ui\bower_components\iron-input\demo\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\test\disabled-input.html">
- <Link>Resources\dashboard-ui\bower_components\iron-input\test\disabled-input.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\test\index.html">
- <Link>Resources\dashboard-ui\bower_components\iron-input\test\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\test\iron-input.html">
- <Link>Resources\dashboard-ui\bower_components\iron-input\test\iron-input.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-input\test\letters-only.html">
- <Link>Resources\dashboard-ui\bower_components\iron-input\test\letters-only.html</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-meta\.bower.json">
<Link>Resources\dashboard-ui\bower_components\iron-meta\.bower.json</Link>
</BundleResource>
@@ -2574,6 +2475,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-meta\iron-meta.html">
<Link>Resources\dashboard-ui\bower_components\iron-meta\iron-meta.html</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-meta\.github\ISSUE_TEMPLATE.md">
+ <Link>Resources\dashboard-ui\bower_components\iron-meta\.github\ISSUE_TEMPLATE.md</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-meta\demo\index.html">
<Link>Resources\dashboard-ui\bower_components\iron-meta\demo\index.html</Link>
</BundleResource>
@@ -2586,45 +2490,6 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-meta\test\iron-meta.html">
<Link>Resources\dashboard-ui\bower_components\iron-meta\test\iron-meta.html</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-range-behavior\.bower.json">
- <Link>Resources\dashboard-ui\bower_components\iron-range-behavior\.bower.json</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-range-behavior\.gitignore">
- <Link>Resources\dashboard-ui\bower_components\iron-range-behavior\.gitignore</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-range-behavior\.travis.yml">
- <Link>Resources\dashboard-ui\bower_components\iron-range-behavior\.travis.yml</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-range-behavior\CONTRIBUTING.md">
- <Link>Resources\dashboard-ui\bower_components\iron-range-behavior\CONTRIBUTING.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-range-behavior\README.md">
- <Link>Resources\dashboard-ui\bower_components\iron-range-behavior\README.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-range-behavior\bower.json">
- <Link>Resources\dashboard-ui\bower_components\iron-range-behavior\bower.json</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-range-behavior\index.html">
- <Link>Resources\dashboard-ui\bower_components\iron-range-behavior\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-range-behavior\iron-range-behavior.html">
- <Link>Resources\dashboard-ui\bower_components\iron-range-behavior\iron-range-behavior.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-range-behavior\.github\ISSUE_TEMPLATE.md">
- <Link>Resources\dashboard-ui\bower_components\iron-range-behavior\.github\ISSUE_TEMPLATE.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-range-behavior\demo\index.html">
- <Link>Resources\dashboard-ui\bower_components\iron-range-behavior\demo\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-range-behavior\test\basic.html">
- <Link>Resources\dashboard-ui\bower_components\iron-range-behavior\test\basic.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-range-behavior\test\index.html">
- <Link>Resources\dashboard-ui\bower_components\iron-range-behavior\test\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-range-behavior\test\x-progressbar.html">
- <Link>Resources\dashboard-ui\bower_components\iron-range-behavior\test\x-progressbar.html</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-validatable-behavior\.bower.json">
<Link>Resources\dashboard-ui\bower_components\iron-validatable-behavior\.bower.json</Link>
</BundleResource>
@@ -3252,126 +3117,6 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-icon-button\test\index.html">
<Link>Resources\dashboard-ui\bower_components\paper-icon-button\test\index.html</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\.bower.json">
- <Link>Resources\dashboard-ui\bower_components\paper-input\.bower.json</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\.gitignore">
- <Link>Resources\dashboard-ui\bower_components\paper-input\.gitignore</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\.travis.yml">
- <Link>Resources\dashboard-ui\bower_components\paper-input\.travis.yml</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\CONTRIBUTING.md">
- <Link>Resources\dashboard-ui\bower_components\paper-input\CONTRIBUTING.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\README.md">
- <Link>Resources\dashboard-ui\bower_components\paper-input\README.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\all-imports.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\all-imports.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\bower.json">
- <Link>Resources\dashboard-ui\bower_components\paper-input\bower.json</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\hero.svg">
- <Link>Resources\dashboard-ui\bower_components\paper-input\hero.svg</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\index.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\paper-input-addon-behavior.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\paper-input-addon-behavior.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\paper-input-behavior.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\paper-input-behavior.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\paper-input-char-counter.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\paper-input-char-counter.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\paper-input-container.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\paper-input-container.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\paper-input-error.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\paper-input-error.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\paper-input.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\paper-input.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\paper-textarea.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\paper-textarea.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\.github\ISSUE_TEMPLATE.md">
- <Link>Resources\dashboard-ui\bower_components\paper-input\.github\ISSUE_TEMPLATE.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\demo\index.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\demo\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\demo\ssn-input.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\demo\ssn-input.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\demo\ssn-validator.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\demo\ssn-validator.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\test\index.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\test\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\test\letters-only.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\test\letters-only.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\test\paper-input-char-counter.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\test\paper-input-char-counter.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\test\paper-input-container.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\test\paper-input-container.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\test\paper-input-error.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\test\paper-input-error.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\test\paper-input.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\test\paper-input.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-input\test\paper-textarea.html">
- <Link>Resources\dashboard-ui\bower_components\paper-input\test\paper-textarea.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-progress\.bower.json">
- <Link>Resources\dashboard-ui\bower_components\paper-progress\.bower.json</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-progress\.gitignore">
- <Link>Resources\dashboard-ui\bower_components\paper-progress\.gitignore</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-progress\.travis.yml">
- <Link>Resources\dashboard-ui\bower_components\paper-progress\.travis.yml</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-progress\CONTRIBUTING.md">
- <Link>Resources\dashboard-ui\bower_components\paper-progress\CONTRIBUTING.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-progress\README.md">
- <Link>Resources\dashboard-ui\bower_components\paper-progress\README.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-progress\bower.json">
- <Link>Resources\dashboard-ui\bower_components\paper-progress\bower.json</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-progress\hero.svg">
- <Link>Resources\dashboard-ui\bower_components\paper-progress\hero.svg</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-progress\index.html">
- <Link>Resources\dashboard-ui\bower_components\paper-progress\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-progress\paper-progress.html">
- <Link>Resources\dashboard-ui\bower_components\paper-progress\paper-progress.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-progress\.github\ISSUE_TEMPLATE.md">
- <Link>Resources\dashboard-ui\bower_components\paper-progress\.github\ISSUE_TEMPLATE.md</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-progress\demo\index.html">
- <Link>Resources\dashboard-ui\bower_components\paper-progress\demo\index.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-progress\test\basic.html">
- <Link>Resources\dashboard-ui\bower_components\paper-progress\test\basic.html</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-progress\test\index.html">
- <Link>Resources\dashboard-ui\bower_components\paper-progress\test\index.html</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\paper-ripple\.bower.json">
<Link>Resources\dashboard-ui\bower_components\paper-ripple\.bower.json</Link>
</BundleResource>
@@ -3729,6 +3474,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\components\tvproviders\xmltv.template.html">
<Link>Resources\dashboard-ui\components\tvproviders\xmltv.template.html</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\css\autoorganizetable.css">
+ <Link>Resources\dashboard-ui\css\autoorganizetable.css</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\css\chromecast.css">
<Link>Resources\dashboard-ui\css\chromecast.css</Link>
</BundleResource>
@@ -3801,6 +3549,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\css\images\rotten.png">
<Link>Resources\dashboard-ui\css\images\rotten.png</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\css\images\throbber.gif">
+ <Link>Resources\dashboard-ui\css\images\throbber.gif</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\css\images\userflyoutdefault.png">
<Link>Resources\dashboard-ui\css\images\userflyoutdefault.png</Link>
</BundleResource>
@@ -3987,6 +3738,48 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\css\images\userdata\password.png">
<Link>Resources\dashboard-ui\css\images\userdata\password.png</Link>
</BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\aboutpage.js">
+ <Link>Resources\dashboard-ui\dashboard\aboutpage.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\autoorganizelog.js">
+ <Link>Resources\dashboard-ui\dashboard\autoorganizelog.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\autoorganizesmart.js">
+ <Link>Resources\dashboard-ui\dashboard\autoorganizesmart.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\autoorganizetv.js">
+ <Link>Resources\dashboard-ui\dashboard\autoorganizetv.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\cinemamodeconfiguration.js">
+ <Link>Resources\dashboard-ui\dashboard\cinemamodeconfiguration.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\dashboardgeneral.js">
+ <Link>Resources\dashboard-ui\dashboard\dashboardgeneral.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\dashboardhosting.js">
+ <Link>Resources\dashboard-ui\dashboard\dashboardhosting.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\devicesupload.js">
+ <Link>Resources\dashboard-ui\dashboard\devicesupload.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\librarydisplay.js">
+ <Link>Resources\dashboard-ui\dashboard\librarydisplay.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\librarysettings.js">
+ <Link>Resources\dashboard-ui\dashboard\librarysettings.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\livetvtunerprovider-satip.js">
+ <Link>Resources\dashboard-ui\dashboard\livetvtunerprovider-satip.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\logpage.js">
+ <Link>Resources\dashboard-ui\dashboard\logpage.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\wizardcomponents.js">
+ <Link>Resources\dashboard-ui\dashboard\wizardcomponents.js</Link>
+ </BundleResource>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\dashboard\wizardfinishpage.js">
+ <Link>Resources\dashboard-ui\dashboard\wizardfinishpage.js</Link>
+ </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\devices\android\android.css">
<Link>Resources\dashboard-ui\devices\android\android.css</Link>
</BundleResource>
@@ -4008,9 +3801,6 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\legacy\selectmenu.js">
<Link>Resources\dashboard-ui\legacy\selectmenu.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\aboutpage.js">
- <Link>Resources\dashboard-ui\scripts\aboutpage.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\addpluginpage.js">
<Link>Resources\dashboard-ui\scripts\addpluginpage.js</Link>
</BundleResource>
@@ -4020,14 +3810,8 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\autobackdrops.js">
<Link>Resources\dashboard-ui\scripts\autobackdrops.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\autoorganizelog.js">
- <Link>Resources\dashboard-ui\scripts\autoorganizelog.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\autoorganizesmart.js">
- <Link>Resources\dashboard-ui\scripts\autoorganizesmart.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\autoorganizetv.js">
- <Link>Resources\dashboard-ui\scripts\autoorganizetv.js</Link>
+ <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\camerauploadsettings.js">
+ <Link>Resources\dashboard-ui\scripts\camerauploadsettings.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\channelitems.js">
<Link>Resources\dashboard-ui\scripts\channelitems.js</Link>
@@ -4041,18 +3825,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\chromecast.js">
<Link>Resources\dashboard-ui\scripts\chromecast.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\cinemamodeconfiguration.js">
- <Link>Resources\dashboard-ui\scripts\cinemamodeconfiguration.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\connectlogin.js">
<Link>Resources\dashboard-ui\scripts\connectlogin.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\dashboardgeneral.js">
- <Link>Resources\dashboard-ui\scripts\dashboardgeneral.js</Link>
- </BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\dashboardhosting.js">
- <Link>Resources\dashboard-ui\scripts\dashboardhosting.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\dashboardpage.js">
<Link>Resources\dashboard-ui\scripts\dashboardpage.js</Link>
</BundleResource>
@@ -4062,9 +3837,6 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\devices.js">
<Link>Resources\dashboard-ui\scripts\devices.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\devicesupload.js">
- <Link>Resources\dashboard-ui\scripts\devicesupload.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\dlnaprofile.js">
<Link>Resources\dashboard-ui\scripts\dlnaprofile.js</Link>
</BundleResource>
@@ -4140,18 +3912,12 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\librarybrowser.js">
<Link>Resources\dashboard-ui\scripts\librarybrowser.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\librarydisplay.js">
- <Link>Resources\dashboard-ui\scripts\librarydisplay.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\librarymenu.js">
<Link>Resources\dashboard-ui\scripts\librarymenu.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\librarypathmapping.js">
<Link>Resources\dashboard-ui\scripts\librarypathmapping.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\librarysettings.js">
- <Link>Resources\dashboard-ui\scripts\librarysettings.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\livetvchannel.js">
<Link>Resources\dashboard-ui\scripts\livetvchannel.js</Link>
</BundleResource>
@@ -4197,18 +3963,12 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\livetvtunerprovider-m3u.js">
<Link>Resources\dashboard-ui\scripts\livetvtunerprovider-m3u.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\livetvtunerprovider-satip.js">
- <Link>Resources\dashboard-ui\scripts\livetvtunerprovider-satip.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\localsync.js">
<Link>Resources\dashboard-ui\scripts\localsync.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\loginpage.js">
<Link>Resources\dashboard-ui\scripts\loginpage.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\logpage.js">
- <Link>Resources\dashboard-ui\scripts\logpage.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\mediacontroller.js">
<Link>Resources\dashboard-ui\scripts\mediacontroller.js</Link>
</BundleResource>
@@ -4371,9 +4131,6 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\supporterkeypage.js">
<Link>Resources\dashboard-ui\scripts\supporterkeypage.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\sync.js">
- <Link>Resources\dashboard-ui\scripts\sync.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\syncactivity.js">
<Link>Resources\dashboard-ui\scripts\syncactivity.js</Link>
</BundleResource>
@@ -4386,9 +4143,6 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\taskbutton.js">
<Link>Resources\dashboard-ui\scripts\taskbutton.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\thememediaplayer.js">
- <Link>Resources\dashboard-ui\scripts\thememediaplayer.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\tvgenres.js">
<Link>Resources\dashboard-ui\scripts\tvgenres.js</Link>
</BundleResource>
@@ -4431,15 +4185,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\wizardagreement.js">
<Link>Resources\dashboard-ui\scripts\wizardagreement.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\wizardcomponents.js">
- <Link>Resources\dashboard-ui\scripts\wizardcomponents.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\wizardcontroller.js">
<Link>Resources\dashboard-ui\scripts\wizardcontroller.js</Link>
</BundleResource>
- <BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\wizardfinishpage.js">
- <Link>Resources\dashboard-ui\scripts\wizardfinishpage.js</Link>
- </BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\wizardlivetvguide.js">
<Link>Resources\dashboard-ui\scripts\wizardlivetvguide.js</Link>
</BundleResource>
diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs
index 4011fa3de3..faf3ba37ea 100644
--- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs
+++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs
@@ -132,7 +132,7 @@ namespace MediaBrowser.Server.Mono.Native
{
get
{
- return Environment.OperatingSystem != Startup.Common.OperatingSystem.Osx;
+ return Environment.OperatingSystem != Startup.Common.OperatingSystem.Osx;
}
}
@@ -187,7 +187,7 @@ namespace MediaBrowser.Server.Mono.Native
{
info.SystemArchitecture = Architecture.X64;
}
- else
+ else
{
info.SystemArchitecture = Architecture.X86;
}
@@ -273,32 +273,11 @@ namespace MediaBrowser.Server.Mono.Native
break;
}
- info.DownloadUrls = GetDownloadUrls(environment);
+ // No version available - user requirement
+ info.DownloadUrls = new string[] { };
return info;
}
-
- private static string[] GetDownloadUrls(NativeEnvironment environment)
- {
- switch (environment.OperatingSystem)
- {
- case OperatingSystem.Linux:
-
- switch (environment.SystemArchitecture)
- {
- case Architecture.X64:
- return new[]
- {
- "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-git-20160215-64bit-static.7z"
- };
- }
- break;
- }
-
- // No version available
- return new string[] { };
- }
-
}
public class NullPowerManagement : IPowerManagement
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index 8cb1d4f0db..9c5015b0ec 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -385,8 +385,7 @@ namespace MediaBrowser.Server.Startup.Common
new OmdbEpisodeProviderMigration(ServerConfigurationManager),
new MovieDbEpisodeProviderMigration(ServerConfigurationManager),
new DbMigration(ServerConfigurationManager, TaskManager),
- new FolderViewSettingMigration(ServerConfigurationManager, UserManager),
- new CollectionGroupingMigration(ServerConfigurationManager, UserManager),
+ new UpdateLevelMigration(ServerConfigurationManager, this, HttpClient, JsonSerializer, _releaseAssetFilename),
new CollectionsViewMigration(ServerConfigurationManager, UserManager)
};
diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
index 808d25fc9c..5ee7d49e86 100644
--- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
+++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
@@ -70,13 +70,12 @@
<Compile Include="FFMpeg\FFMpegInfo.cs" />
<Compile Include="INativeApp.cs" />
<Compile Include="MbLinkShortcutHandler.cs" />
- <Compile Include="Migrations\CollectionGroupingMigration.cs" />
<Compile Include="Migrations\CollectionsViewMigration.cs" />
- <Compile Include="Migrations\FolderViewSettingMigration.cs" />
<Compile Include="Migrations\IVersionMigration.cs" />
<Compile Include="Migrations\DbMigration.cs" />
<Compile Include="Migrations\MovieDbEpisodeProviderMigration.cs" />
<Compile Include="Migrations\OmdbEpisodeProviderMigration.cs" />
+ <Compile Include="Migrations\UpdateLevelMigration.cs" />
<Compile Include="NativeEnvironment.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StartupOptions.cs" />
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/CollectionGroupingMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/CollectionGroupingMigration.cs
deleted file mode 100644
index 5041c49b8b..0000000000
--- a/MediaBrowser.Server.Startup.Common/Migrations/CollectionGroupingMigration.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System.Linq;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Library;
-
-namespace MediaBrowser.Server.Startup.Common.Migrations
-{
- public class CollectionGroupingMigration : IVersionMigration
- {
- private readonly IServerConfigurationManager _config;
- private readonly IUserManager _userManager;
-
- public CollectionGroupingMigration(IServerConfigurationManager config, IUserManager userManager)
- {
- _config = config;
- _userManager = userManager;
- }
-
- public void Run()
- {
- var migrationKey = this.GetType().Name;
- var migrationKeyList = _config.Configuration.Migrations.ToList();
-
- if (!migrationKeyList.Contains(migrationKey))
- {
- if (_config.Configuration.IsStartupWizardCompleted)
- {
- if (_userManager.Users.Any(i => i.Configuration.GroupMoviesIntoBoxSets))
- {
- _config.Configuration.EnableGroupingIntoCollections = true;
- }
- }
-
- migrationKeyList.Add(migrationKey);
- _config.Configuration.Migrations = migrationKeyList.ToArray();
- _config.SaveConfiguration();
- }
-
- }
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs
deleted file mode 100644
index 12054864b3..0000000000
--- a/MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System.Linq;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Library;
-
-namespace MediaBrowser.Server.Startup.Common.Migrations
-{
- public class FolderViewSettingMigration : IVersionMigration
- {
- private readonly IServerConfigurationManager _config;
- private readonly IUserManager _userManager;
-
- public FolderViewSettingMigration(IServerConfigurationManager config, IUserManager userManager)
- {
- _config = config;
- _userManager = userManager;
- }
-
- public void Run()
- {
- var migrationKey = this.GetType().Name;
- var migrationKeyList = _config.Configuration.Migrations.ToList();
-
- if (!migrationKeyList.Contains(migrationKey))
- {
- if (_config.Configuration.IsStartupWizardCompleted)
- {
- if (_userManager.Users.Any(i => i.Configuration.DisplayFoldersView))
- {
- _config.Configuration.EnableFolderView = true;
- }
- }
-
- migrationKeyList.Add(migrationKey);
- _config.Configuration.Migrations = migrationKeyList.ToArray();
- _config.SaveConfiguration();
- }
-
- }
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs
new file mode 100644
index 0000000000..fa354065c3
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Implementations.Updates;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Updates;
+
+namespace MediaBrowser.Server.Startup.Common.Migrations
+{
+ public class UpdateLevelMigration : IVersionMigration
+ {
+ private readonly IServerConfigurationManager _config;
+ private readonly IServerApplicationHost _appHost;
+ private readonly IHttpClient _httpClient;
+ private readonly IJsonSerializer _jsonSerializer;
+ private readonly string _releaseAssetFilename;
+
+ public UpdateLevelMigration(IServerConfigurationManager config, IServerApplicationHost appHost, IHttpClient httpClient, IJsonSerializer jsonSerializer, string releaseAssetFilename)
+ {
+ _config = config;
+ _appHost = appHost;
+ _httpClient = httpClient;
+ _jsonSerializer = jsonSerializer;
+ _releaseAssetFilename = releaseAssetFilename;
+ }
+
+ public async void Run()
+ {
+ var lastVersion = _config.Configuration.LastVersion;
+ var currentVersion = _appHost.ApplicationVersion;
+
+ if (string.Equals(lastVersion, currentVersion.ToString(), StringComparison.OrdinalIgnoreCase))
+ {
+ return;
+ }
+
+ try
+ {
+ var updateLevel = _config.Configuration.SystemUpdateLevel;
+
+ // Go down a level
+ if (updateLevel == PackageVersionClass.Release)
+ {
+ updateLevel = PackageVersionClass.Beta;
+ }
+ else if (updateLevel == PackageVersionClass.Beta)
+ {
+ updateLevel = PackageVersionClass.Dev;
+ }
+ else if (updateLevel == PackageVersionClass.Dev)
+ {
+ // It's already dev, there's nothing to check
+ return;
+ }
+
+ await CheckVersion(currentVersion, updateLevel, CancellationToken.None).ConfigureAwait(false);
+ }
+ catch
+ {
+
+ }
+ }
+
+ private async Task CheckVersion(Version currentVersion, PackageVersionClass updateLevel, CancellationToken cancellationToken)
+ {
+ var result = await new GithubUpdater(_httpClient, _jsonSerializer, TimeSpan.FromMinutes(5))
+ .CheckForUpdateResult("MediaBrowser", "Emby", currentVersion, PackageVersionClass.Beta, _releaseAssetFilename, "MBServer", "Mbserver.zip",
+ cancellationToken).ConfigureAwait(false);
+
+ if (result != null && result.IsUpdateAvailable)
+ {
+ _config.Configuration.SystemUpdateLevel = updateLevel;
+ _config.SaveConfiguration();
+ return;
+ }
+
+ // Go down a level
+ if (updateLevel == PackageVersionClass.Release)
+ {
+ updateLevel = PackageVersionClass.Beta;
+ }
+ else if (updateLevel == PackageVersionClass.Beta)
+ {
+ updateLevel = PackageVersionClass.Dev;
+ }
+ else
+ {
+ return;
+ }
+
+ await CheckVersion(currentVersion, updateLevel, cancellationToken).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index 601ebfba73..aec4632ae8 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -157,11 +157,21 @@ namespace MediaBrowser.WebDashboard.Api
var creator = GetPackageCreator();
var directory = creator.DashboardUIPath;
- var skipExtensions = GetUndeployedExtensions();
+ var skipExtensions = GetDeployIgnoreExtensions();
+ var skipNames = GetDeployIgnoreFilenames();
return
Directory.GetFiles(directory, "*", SearchOption.AllDirectories)
.Where(i => !skipExtensions.Contains(Path.GetExtension(i) ?? string.Empty, StringComparer.OrdinalIgnoreCase))
+ .Where(i => !skipNames.Any(s =>
+ {
+ if (s.Item2)
+ {
+ return string.Equals(s.Item1, Path.GetFileName(i), StringComparison.OrdinalIgnoreCase);
+ }
+
+ return (Path.GetFileName(i) ?? string.Empty).IndexOf(s.Item1, StringComparison.OrdinalIgnoreCase) != -1;
+ }))
.Select(i => i.Replace(directory, string.Empty, StringComparison.OrdinalIgnoreCase).Replace("\\", "/").TrimStart('/') + "?v=" + _appHost.ApplicationVersion.ToString())
.ToList();
}
@@ -300,7 +310,7 @@ namespace MediaBrowser.WebDashboard.Api
return new PackageCreator(_fileSystem, _localization, Logger, _serverConfigurationManager, _jsonSerializer);
}
- private List<string> GetUndeployedExtensions()
+ private List<string> GetDeployIgnoreExtensions()
{
var list = new List<string>();
@@ -315,6 +325,28 @@ namespace MediaBrowser.WebDashboard.Api
return list;
}
+ private List<Tuple<string,bool>> GetDeployIgnoreFilenames()
+ {
+ var list = new List<Tuple<string, bool>>();
+
+ list.Add(new Tuple<string, bool>("copying", true));
+ list.Add(new Tuple<string, bool>("license", true));
+ list.Add(new Tuple<string, bool>("license-mit", true));
+ list.Add(new Tuple<string, bool>("gitignore", false));
+ list.Add(new Tuple<string, bool>("npmignore", false));
+ list.Add(new Tuple<string, bool>("jshintrc", false));
+ list.Add(new Tuple<string, bool>("gruntfile", false));
+ list.Add(new Tuple<string, bool>("bowerrc", false));
+ list.Add(new Tuple<string, bool>("jscsrc", false));
+ list.Add(new Tuple<string, bool>("hero.svg", false));
+ list.Add(new Tuple<string, bool>("travis.yml", false));
+ list.Add(new Tuple<string, bool>("build.js", false));
+ list.Add(new Tuple<string, bool>("editorconfig", false));
+ list.Add(new Tuple<string, bool>("gitattributes", false));
+
+ return list;
+ }
+
public async Task<object> Get(GetDashboardPackage request)
{
var path = Path.Combine(_serverConfigurationManager.ApplicationPaths.ProgramDataPath,
@@ -344,30 +376,12 @@ namespace MediaBrowser.WebDashboard.Api
// Try to trim the output size a bit
var bowerPath = Path.Combine(path, "bower_components");
- if (!string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase))
- {
- //var versionedBowerPath = Path.Combine(Path.GetDirectoryName(bowerPath), "bower_components" + _appHost.ApplicationVersion);
- //Directory.Move(bowerPath, versionedBowerPath);
- //bowerPath = versionedBowerPath;
- }
-
- GetUndeployedExtensions().ForEach(i => DeleteFilesByExtension(bowerPath, i));
+ GetDeployIgnoreExtensions().ForEach(i => DeleteFilesByExtension(bowerPath, i));
DeleteFilesByExtension(bowerPath, ".json", "strings\\");
- DeleteFilesByName(bowerPath, "copying", true);
- DeleteFilesByName(bowerPath, "license", true);
- DeleteFilesByName(bowerPath, "license-mit", true);
- DeleteFilesByName(bowerPath, "gitignore");
- DeleteFilesByName(bowerPath, "npmignore");
- DeleteFilesByName(bowerPath, "jshintrc");
- DeleteFilesByName(bowerPath, "gruntfile");
- DeleteFilesByName(bowerPath, "bowerrc");
- DeleteFilesByName(bowerPath, "jscsrc");
- DeleteFilesByName(bowerPath, "hero.svg");
- DeleteFilesByName(bowerPath, "travis.yml");
- DeleteFilesByName(bowerPath, "build.js");
- DeleteFilesByName(bowerPath, "editorconfig");
- DeleteFilesByName(bowerPath, "gitattributes");
+
+ GetDeployIgnoreFilenames().ForEach(i => DeleteFilesByName(bowerPath, i.Item1, i.Item2));
+
DeleteFoldersByName(bowerPath, "demo");
DeleteFoldersByName(bowerPath, "test");
DeleteFoldersByName(bowerPath, "guides");
@@ -382,8 +396,6 @@ namespace MediaBrowser.WebDashboard.Api
}
_fileSystem.DeleteDirectory(Path.Combine(bowerPath, "jquery", "src"), true);
- //_fileSystem.DeleteDirectory(Path.Combine(bowerPath, "fingerprintjs2", "flash"), true);
- //_fileSystem.DeleteDirectory(Path.Combine(bowerPath, "fingerprintjs2", "specs"), true);
DeleteCryptoFiles(Path.Combine(bowerPath, "cryptojslib", "components"));
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index 61facf8ec4..5b66c27f48 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -101,6 +101,9 @@
<Content Include="dashboard-ui\autoorganizesmart.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\camerauploadsettings.html">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\components\appfooter\appfooter.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -182,6 +185,12 @@
<Content Include="dashboard-ui\components\tvproviders\xmltv.template.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\css\images\throbber.gif">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="dashboard-ui\scripts\camerauploadsettings.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\scripts\userpasswordpage.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -191,6 +200,9 @@
<Content Include="dashboard-ui\css\dashboard.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\css\autoorganizetable.css">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\css\images\logo.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -320,7 +332,7 @@
<Content Include="dashboard-ui\scripts\homeupcoming.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\librarydisplay.js">
+ <Content Include="dashboard-ui\dashboard\librarydisplay.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\livetvguideprovider.js">
@@ -332,7 +344,7 @@
<Content Include="dashboard-ui\scripts\livetvtunerprovider-m3u.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\livetvtunerprovider-satip.js">
+ <Content Include="dashboard-ui\dashboard\livetvtunerprovider-satip.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\localsync.js">
@@ -350,7 +362,7 @@
<Content Include="dashboard-ui\scripts\mysyncsettings.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\autoorganizesmart.js">
+ <Content Include="dashboard-ui\dashboard\autoorganizesmart.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\searchpage.js">
@@ -371,7 +383,7 @@
<Content Include="dashboard-ui\scripts\tvlatest.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\wizardcomponents.js">
+ <Content Include="dashboard-ui\dashboard\wizardcomponents.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\wizardcontroller.js">
@@ -497,7 +509,7 @@
<Content Include="dashboard-ui\photos.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\dashboardhosting.js">
+ <Content Include="dashboard-ui\dashboard\dashboardhosting.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\forgotpassword.js">
@@ -857,13 +869,13 @@
<Content Include="dashboard-ui\scripts\chromecast.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\cinemamodeconfiguration.js">
+ <Content Include="dashboard-ui\dashboard\cinemamodeconfiguration.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\connectlogin.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\dashboardgeneral.js">
+ <Content Include="dashboard-ui\dashboard\dashboardgeneral.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\syncactivity.js">
@@ -875,7 +887,7 @@
<Content Include="dashboard-ui\scripts\devices.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\devicesupload.js">
+ <Content Include="dashboard-ui\dashboard\devicesupload.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\dlnaprofile.js">
@@ -890,10 +902,10 @@
<Content Include="dashboard-ui\scripts\encodingsettings.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\autoorganizetv.js">
+ <Content Include="dashboard-ui\dashboard\autoorganizetv.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\autoorganizelog.js">
+ <Content Include="dashboard-ui\dashboard\autoorganizelog.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\externalplayer.js">
@@ -989,12 +1001,6 @@
<Content Include="dashboard-ui\scripts\livetvsuggested.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\sync.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\scripts\thememediaplayer.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\scripts\tvupcoming.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -1086,7 +1092,7 @@
<Content Include="dashboard-ui\scripts\edititemmetadata.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\librarysettings.js">
+ <Content Include="dashboard-ui\dashboard\librarysettings.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\musicrecommended.js">
@@ -1353,7 +1359,7 @@
</Content>
</ItemGroup>
<ItemGroup>
- <Content Include="dashboard-ui\scripts\logpage.js">
+ <Content Include="dashboard-ui\dashboard\logpage.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
@@ -1426,7 +1432,7 @@
</Content>
</ItemGroup>
<ItemGroup>
- <Content Include="dashboard-ui\scripts\aboutpage.js">
+ <Content Include="dashboard-ui\dashboard\aboutpage.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\supporter\supporterflag.png">
@@ -1438,7 +1444,7 @@
<Content Include="dashboard-ui\itemlist.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\wizardfinishpage.js">
+ <Content Include="dashboard-ui\dashboard\wizardfinishpage.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\items\detail\video.png">
diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
index 0c8501e626..f777ae16bc 100644
--- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
+++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
@@ -827,6 +827,15 @@ namespace MediaBrowser.XbmcMetadata.Parsers
}
break;
}
+ case "tvmazeid":
+ {
+ var id = reader.ReadElementContentAsString();
+ if (!string.IsNullOrWhiteSpace(id))
+ {
+ item.SetProviderId(MetadataProviders.TvMaze, id);
+ }
+ break;
+ }
case "audiodbartistid":
{
var id = reader.ReadElementContentAsString();
diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
index 954fb2a474..c28a15a939 100644
--- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
+++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
@@ -822,6 +822,12 @@ namespace MediaBrowser.XbmcMetadata.Savers
writer.WriteElementString("tvrageid", externalId);
}
+ externalId = item.GetProviderId(MetadataProviders.TvMaze);
+ if (!string.IsNullOrEmpty(externalId))
+ {
+ writer.WriteElementString("tvmazeid", externalId);
+ }
+
if (options.SaveImagePathsInNfo)
{
AddImages(item, writer, libraryManager, config);
diff --git a/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs
index 7523ce6bf1..6380b9f53b 100644
--- a/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs
+++ b/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs
@@ -118,7 +118,9 @@ namespace MediaBrowser.XbmcMetadata.Savers
"airsbefore_season",
"DVD_episodenumber",
"DVD_season",
- "absolute_number"
+ "absolute_number",
+ "displayseason",
+ "displayepisode"
};
return list;
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index e96a77e647..d1c4c0b449 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.654</version>
+ <version>3.0.655</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Emby 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.654" />
+ <dependency id="MediaBrowser.Common" version="3.0.655" />
<dependency id="NLog" version="4.3.6" />
<dependency id="SimpleInjector" version="3.2.0" />
</dependencies>
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index ada11fd45a..ffee84de2e 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.654</version>
+ <version>3.0.655</version>
<title>MediaBrowser.Common</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index f4a79f454f..73c51ca355 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.654</version>
+ <version>3.0.655</version>
<title>Media Browser.Server.Core</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Emby Server.</description>
<copyright>Copyright © Emby 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.654" />
+ <dependency id="MediaBrowser.Common" version="3.0.655" />
<dependency id="Interfaces.IO" version="1.0.0.5" />
</dependencies>
</metadata>