aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MediaBrowser.Api/ApiEntryPoint.cs11
-rw-r--r--MediaBrowser.Api/Library/LibraryStructureService.cs7
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs27
-rw-r--r--MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs70
-rw-r--r--MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs16
-rw-r--r--MediaBrowser.Controller/Configuration/LibraryOptions.cs14
-rw-r--r--MediaBrowser.Controller/Entities/Audio/Audio.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicArtist.cs8
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicGenre.cs8
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs17
-rw-r--r--MediaBrowser.Controller/Entities/Book.cs2
-rw-r--r--MediaBrowser.Controller/Entities/CollectionFolder.cs60
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs4
-rw-r--r--MediaBrowser.Controller/Entities/Game.cs2
-rw-r--r--MediaBrowser.Controller/Entities/GameGenre.cs7
-rw-r--r--MediaBrowser.Controller/Entities/Genre.cs8
-rw-r--r--MediaBrowser.Controller/Entities/IHasMetadata.cs10
-rw-r--r--MediaBrowser.Controller/Entities/Movies/BoxSet.cs13
-rw-r--r--MediaBrowser.Controller/Entities/Person.cs8
-rw-r--r--MediaBrowser.Controller/Entities/Photo.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Studio.cs8
-rw-r--r--MediaBrowser.Controller/Entities/TV/Season.cs18
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs30
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Video.cs21
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs18
-rw-r--r--MediaBrowser.Controller/Library/ItemResolveArgs.cs8
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj1
-rw-r--r--MediaBrowser.Controller/Playlists/Playlist.cs6
-rw-r--r--MediaBrowser.Dlna/DlnaManager.cs7
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs6
-rw-r--r--MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs6
-rw-r--r--MediaBrowser.Model/ApiClient/IApiClient.cs2
-rw-r--r--MediaBrowser.Model/Configuration/ServerConfiguration.cs2
-rw-r--r--MediaBrowser.Providers/Manager/MetadataService.cs9
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs9
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs2
-rw-r--r--MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs9
-rw-r--r--MediaBrowser.Providers/TV/SeasonMetadataService.cs21
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs2
-rw-r--r--MediaBrowser.Server.Implementations/IO/FileRefresher.cs7
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs78
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs30
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs7
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs2
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs17
-rw-r--r--MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs2
-rw-r--r--MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs2
-rw-r--r--MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs2
-rw-r--r--MediaBrowser.Server.Startup.Common/ApplicationHost.cs1
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardService.cs61
-rw-r--r--MediaBrowser.WebDashboard/Api/PackageCreator.cs10
-rw-r--r--MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj17
58 files changed, 484 insertions, 253 deletions
diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs
index 1a7f4a2b1..bb9d2b864 100644
--- a/MediaBrowser.Api/ApiEntryPoint.cs
+++ b/MediaBrowser.Api/ApiEntryPoint.cs
@@ -63,6 +63,15 @@ namespace MediaBrowser.Api
Instance = this;
_sessionManager.PlaybackProgress += _sessionManager_PlaybackProgress;
+ _sessionManager.PlaybackStart += _sessionManager_PlaybackStart;
+ }
+
+ private void _sessionManager_PlaybackStart(object sender, PlaybackProgressEventArgs e)
+ {
+ if (!string.IsNullOrWhiteSpace(e.PlaySessionId))
+ {
+ PingTranscodingJob(e.PlaySessionId, e.IsPaused);
+ }
}
void _sessionManager_PlaybackProgress(object sender, PlaybackProgressEventArgs e)
@@ -401,7 +410,7 @@ namespace MediaBrowser.Api
}
}
- Logger.Debug("Transcoding kill timer stopped for JobId {0} PlaySessionId {1}. Killing transcoding", job.Id, job.PlaySessionId);
+ Logger.Info("Transcoding kill timer stopped for JobId {0} PlaySessionId {1}. Killing transcoding", job.Id, job.PlaySessionId);
KillTranscodingJob(job, true, path => true);
}
diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs
index 3cf0d5d93..3af213493 100644
--- a/MediaBrowser.Api/Library/LibraryStructureService.cs
+++ b/MediaBrowser.Api/Library/LibraryStructureService.cs
@@ -10,6 +10,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Controller.Configuration;
namespace MediaBrowser.Api.Library
{
@@ -52,6 +53,8 @@ namespace MediaBrowser.Api.Library
/// </summary>
/// <value>The path.</value>
public string[] Paths { get; set; }
+
+ public LibraryOptions LibraryOptions { get; set; }
}
[Route("/Library/VirtualFolders", "DELETE")]
@@ -190,7 +193,9 @@ namespace MediaBrowser.Api.Library
/// <param name="request">The request.</param>
public void Post(AddVirtualFolder request)
{
- _libraryManager.AddVirtualFolder(request.Name, request.CollectionType, request.Paths, request.RefreshLibrary);
+ var libraryOptions = request.LibraryOptions ?? new LibraryOptions();
+
+ _libraryManager.AddVirtualFolder(request.Name, request.CollectionType, request.Paths, libraryOptions, request.RefreshLibrary);
}
/// <summary>
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 164d607d2..a9489cecc 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -1055,14 +1055,14 @@ namespace MediaBrowser.Api.Playback
var commandLineLogMessage = process.StartInfo.FileName + " " + process.StartInfo.Arguments;
Logger.Info(commandLineLogMessage);
- var logFilePrefix = "transcode";
+ var logFilePrefix = "ffmpeg-transcode";
if (state.VideoRequest != null && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase))
{
- logFilePrefix = "directstream";
+ logFilePrefix = "ffmpeg-directstream";
}
else if (state.VideoRequest != null && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
{
- logFilePrefix = "remux";
+ logFilePrefix = "ffmpeg-remux";
}
var logFilePath = Path.Combine(ServerConfigurationManager.ApplicationPaths.LogDirectoryPath, logFilePrefix + "-" + Guid.NewGuid() + ".txt");
@@ -1118,22 +1118,23 @@ namespace MediaBrowser.Api.Playback
private void StartThrottler(StreamState state, TranscodingJob transcodingJob)
{
- if (EnableThrottling(state) && state.InputProtocol == MediaProtocol.File &&
- state.RunTimeTicks.HasValue &&
- state.VideoType == VideoType.VideoFile &&
- !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
+ if (EnableThrottling(state) && !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
{
- if (state.RunTimeTicks.Value >= TimeSpan.FromMinutes(5).Ticks && state.IsInputVideo)
- {
- transcodingJob.TranscodingThrottler = state.TranscodingThrottler = new TranscodingThrottler(transcodingJob, Logger, ServerConfigurationManager);
- state.TranscodingThrottler.Start();
- }
+ transcodingJob.TranscodingThrottler = state.TranscodingThrottler = new TranscodingThrottler(transcodingJob, Logger, ServerConfigurationManager);
+ state.TranscodingThrottler.Start();
}
}
protected virtual bool EnableThrottling(StreamState state)
{
- return true;
+ // do not use throttling with hardware encoders
+ return state.InputProtocol == MediaProtocol.File &&
+ state.RunTimeTicks.HasValue &&
+ state.RunTimeTicks.Value >= TimeSpan.FromMinutes(5).Ticks &&
+ state.IsInputVideo &&
+ state.VideoType == VideoType.VideoFile &&
+ !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) &&
+ string.Equals(GetVideoEncoder(state), "libx264", StringComparison.OrdinalIgnoreCase);
}
private async Task StartStreamingLog(TranscodingJob transcodingJob, StreamState state, Stream source, Stream target)
diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
index 4649499c4..f4cc9f4bc 100644
--- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
@@ -165,40 +165,40 @@ namespace MediaBrowser.Api.Playback.Progressive
}
}
- // Not static but transcode cache file exists
- if (isTranscodeCached)
- {
- var contentType = state.GetMimeType(outputPath);
-
- try
- {
- if (transcodingJob != null)
- {
- ApiEntryPoint.Instance.OnTranscodeBeginRequest(transcodingJob);
- }
-
- return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
- {
- ResponseHeaders = responseHeaders,
- ContentType = contentType,
- IsHeadRequest = isHeadRequest,
- Path = outputPath,
- FileShare = FileShare.ReadWrite,
- OnComplete = () =>
- {
- if (transcodingJob != null)
- {
- ApiEntryPoint.Instance.OnTranscodeEndRequest(transcodingJob);
- }
- }
-
- }).ConfigureAwait(false);
- }
- finally
- {
- state.Dispose();
- }
- }
+ //// Not static but transcode cache file exists
+ //if (isTranscodeCached && state.VideoRequest == null)
+ //{
+ // var contentType = state.GetMimeType(outputPath);
+
+ // try
+ // {
+ // if (transcodingJob != null)
+ // {
+ // ApiEntryPoint.Instance.OnTranscodeBeginRequest(transcodingJob);
+ // }
+
+ // return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
+ // {
+ // ResponseHeaders = responseHeaders,
+ // ContentType = contentType,
+ // IsHeadRequest = isHeadRequest,
+ // Path = outputPath,
+ // FileShare = FileShare.ReadWrite,
+ // OnComplete = () =>
+ // {
+ // if (transcodingJob != null)
+ // {
+ // ApiEntryPoint.Instance.OnTranscodeEndRequest(transcodingJob);
+ // }
+ // }
+
+ // }).ConfigureAwait(false);
+ // }
+ // finally
+ // {
+ // state.Dispose();
+ // }
+ //}
// Need to start ffmpeg
try
@@ -383,7 +383,7 @@ namespace MediaBrowser.Api.Playback.Progressive
if (totalBitrate > 0 && state.RunTimeTicks.HasValue)
{
- return Convert.ToInt64(totalBitrate * TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalSeconds);
+ return Convert.ToInt64(totalBitrate * TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalSeconds / 8);
}
return null;
diff --git a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
index 756741e0d..77f65b0c7 100644
--- a/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
+++ b/MediaBrowser.Common.Implementations/Serialization/XmlSerializer.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Concurrent;
+using System.Collections.Generic;
using System.IO;
using System.Xml;
using CommonIO;
@@ -24,13 +25,22 @@ namespace MediaBrowser.Common.Implementations.Serialization
// Need to cache these
// http://dotnetcodebox.blogspot.com/2013/01/xmlserializer-class-may-result-in.html
- private readonly ConcurrentDictionary<string, System.Xml.Serialization.XmlSerializer> _serializers =
- new ConcurrentDictionary<string, System.Xml.Serialization.XmlSerializer>();
+ private readonly Dictionary<string, System.Xml.Serialization.XmlSerializer> _serializers =
+ new Dictionary<string, System.Xml.Serialization.XmlSerializer>();
private System.Xml.Serialization.XmlSerializer GetSerializer(Type type)
{
var key = type.FullName;
- return _serializers.GetOrAdd(key, k => new System.Xml.Serialization.XmlSerializer(type));
+ lock (_serializers)
+ {
+ System.Xml.Serialization.XmlSerializer serializer;
+ if (!_serializers.TryGetValue(key, out serializer))
+ {
+ serializer = new System.Xml.Serialization.XmlSerializer(type);
+ _serializers[key] = serializer;
+ }
+ return serializer;
+ }
}
/// <summary>
diff --git a/MediaBrowser.Controller/Configuration/LibraryOptions.cs b/MediaBrowser.Controller/Configuration/LibraryOptions.cs
new file mode 100644
index 000000000..1a824c08b
--- /dev/null
+++ b/MediaBrowser.Controller/Configuration/LibraryOptions.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Controller.Configuration
+{
+ public class LibraryOptions
+ {
+ public bool EnableAudioArchiveFiles { get; set; }
+ public bool EnableVideoArchiveFiles { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs
index 1897511af..6326bbd4f 100644
--- a/MediaBrowser.Controller/Entities/Audio/Audio.cs
+++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs
@@ -47,7 +47,7 @@ namespace MediaBrowser.Controller.Entities.Audio
}
[IgnoreDataMember]
- public override bool EnableForceSaveOnDateModifiedChange
+ public override bool EnableRefreshOnDateModifiedChange
{
get { return true; }
}
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
index 6790a1bcf..56f9a5b88 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
@@ -169,13 +169,9 @@ namespace MediaBrowser.Controller.Entities.Audio
list.Add("Artist-" + (item.Name ?? string.Empty).RemoveDiacritics());
return list;
}
-
- public override string PresentationUniqueKey
+ public override string CreatePresentationUniqueKey()
{
- get
- {
- return "Artist-" + (Name ?? string.Empty).RemoveDiacritics();
- }
+ return "Artist-" + (Name ?? string.Empty).RemoveDiacritics();
}
protected override bool GetBlockUnratedValue(UserPolicy config)
{
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
index 798bc79fb..9aa5625fa 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
@@ -18,13 +18,9 @@ namespace MediaBrowser.Controller.Entities.Audio
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
return list;
}
-
- public override string PresentationUniqueKey
+ public override string CreatePresentationUniqueKey()
{
- get
- {
- return GetUserDataKeys()[0];
- }
+ return GetUserDataKeys()[0];
}
[IgnoreDataMember]
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 8d00f38be..cc3646cdc 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -455,7 +455,7 @@ namespace MediaBrowser.Controller.Entities
public DateTime DateLastRefreshed { get; set; }
[IgnoreDataMember]
- public virtual bool EnableForceSaveOnDateModifiedChange
+ public virtual bool EnableRefreshOnDateModifiedChange
{
get { return false; }
}
@@ -951,7 +951,7 @@ namespace MediaBrowser.Controller.Entities
.Where(i => !i.IsDirectory && string.Equals(FileSystem.GetFileNameWithoutExtension(i), ThemeSongFilename, StringComparison.OrdinalIgnoreCase))
);
- return LibraryManager.ResolvePaths(files, directoryService, null)
+ return LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions())
.OfType<Audio.Audio>()
.Select(audio =>
{
@@ -981,7 +981,7 @@ namespace MediaBrowser.Controller.Entities
.Where(i => string.Equals(i.Name, ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase))
.SelectMany(i => directoryService.GetFiles(i.FullName));
- return LibraryManager.ResolvePaths(files, directoryService, null)
+ return LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions())
.OfType<Video>()
.Select(item =>
{
@@ -1194,10 +1194,17 @@ namespace MediaBrowser.Controller.Entities
get { return null; }
}
+ public virtual string CreatePresentationUniqueKey()
+ {
+ return Id.ToString("N");
+ }
+
[IgnoreDataMember]
- public virtual string PresentationUniqueKey
+ public string PresentationUniqueKey { get; set; }
+
+ public string GetPresentationUniqueKey()
{
- get { return Id.ToString("N"); }
+ return PresentationUniqueKey ?? CreatePresentationUniqueKey();
}
public virtual bool RequiresRefresh()
diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs
index 59ab95437..56f9fa784 100644
--- a/MediaBrowser.Controller/Entities/Book.cs
+++ b/MediaBrowser.Controller/Entities/Book.cs
@@ -35,7 +35,7 @@ namespace MediaBrowser.Controller.Entities
}
[IgnoreDataMember]
- public override bool EnableForceSaveOnDateModifiedChange
+ public override bool EnableRefreshOnDateModifiedChange
{
get { return true; }
}
diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs
index 8bf9919f2..289cb7a2e 100644
--- a/MediaBrowser.Controller/Entities/CollectionFolder.cs
+++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs
@@ -3,11 +3,14 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Model.Serialization;
using MoreLinq;
namespace MediaBrowser.Controller.Entities
@@ -18,6 +21,8 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public class CollectionFolder : Folder, ICollectionFolder
{
+ public static IXmlSerializer XmlSerializer { get; set; }
+
public CollectionFolder()
{
PhysicalLocationsList = new List<string>();
@@ -39,6 +44,61 @@ namespace MediaBrowser.Controller.Entities
public string CollectionType { get; set; }
+ private static readonly Dictionary<string, LibraryOptions> LibraryOptions = new Dictionary<string, LibraryOptions>();
+ public LibraryOptions GetLibraryOptions()
+ {
+ lock (LibraryOptions)
+ {
+ LibraryOptions options;
+ if (!LibraryOptions.TryGetValue(Path, out options))
+ {
+ options = LoadLibraryOptions();
+ LibraryOptions[Path] = options;
+ }
+
+ return options;
+ }
+ }
+
+ private LibraryOptions LoadLibraryOptions()
+ {
+ try
+ {
+ var result = XmlSerializer.DeserializeFromFile(typeof(LibraryOptions), GetLibraryOptionsPath(Path)) as LibraryOptions;
+
+ if (result == null)
+ {
+ return new LibraryOptions();
+ }
+
+ return result;
+ }
+ catch (FileNotFoundException)
+ {
+ return new LibraryOptions();
+ }
+ catch (DirectoryNotFoundException)
+ {
+ return new LibraryOptions();
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error loading library options", ex);
+
+ return new LibraryOptions();
+ }
+ }
+
+ private static string GetLibraryOptionsPath(string path)
+ {
+ return System.IO.Path.Combine(path, "options.xml");
+ }
+
+ public static void SaveLibraryOptions(string path, LibraryOptions options)
+ {
+ XmlSerializer.SerializeToFile(options, GetLibraryOptionsPath(path));
+ }
+
/// <summary>
/// Allow different display preferences for each collection folder
/// </summary>
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index c1728ce38..bf04c643c 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -273,6 +273,7 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
protected virtual IEnumerable<BaseItem> LoadChildren()
{
+ //Logger.Debug("Loading children from {0} {1}", Id, Path);
//just load our children from the repo - the library will be validated and maintained in other processes
return GetCachedChildren();
}
@@ -643,8 +644,9 @@ namespace MediaBrowser.Controller.Entities
protected virtual IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
{
var collectionType = LibraryManager.GetContentType(this);
+ var libraryOptions = LibraryManager.GetLibraryOptions(this);
- return LibraryManager.ResolvePaths(GetFileSystemChildren(directoryService), directoryService, this, collectionType);
+ return LibraryManager.ResolvePaths(GetFileSystemChildren(directoryService), directoryService, this, libraryOptions, collectionType);
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs
index 54386a179..24910498f 100644
--- a/MediaBrowser.Controller/Entities/Game.cs
+++ b/MediaBrowser.Controller/Entities/Game.cs
@@ -34,7 +34,7 @@ namespace MediaBrowser.Controller.Entities
}
[IgnoreDataMember]
- public override bool EnableForceSaveOnDateModifiedChange
+ public override bool EnableRefreshOnDateModifiedChange
{
get { return true; }
}
diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs
index 45e766c0f..5d66bf3ab 100644
--- a/MediaBrowser.Controller/Entities/GameGenre.cs
+++ b/MediaBrowser.Controller/Entities/GameGenre.cs
@@ -16,12 +16,9 @@ namespace MediaBrowser.Controller.Entities
return list;
}
- public override string PresentationUniqueKey
+ public override string CreatePresentationUniqueKey()
{
- get
- {
- return GetUserDataKeys()[0];
- }
+ return GetUserDataKeys()[0];
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs
index cc5aebb2a..c7fe25a96 100644
--- a/MediaBrowser.Controller/Entities/Genre.cs
+++ b/MediaBrowser.Controller/Entities/Genre.cs
@@ -19,13 +19,9 @@ namespace MediaBrowser.Controller.Entities
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
return list;
}
-
- public override string PresentationUniqueKey
+ public override string CreatePresentationUniqueKey()
{
- get
- {
- return GetUserDataKeys()[0];
- }
+ return GetUserDataKeys()[0];
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs
index 378c4a390..d5891c655 100644
--- a/MediaBrowser.Controller/Entities/IHasMetadata.cs
+++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs
@@ -32,7 +32,7 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <value>The date last refreshed.</value>
DateTime DateLastRefreshed { get; set; }
-
+
/// <summary>
/// This is called before any metadata refresh and returns true or false indicating if changes were made
/// </summary>
@@ -52,6 +52,12 @@ namespace MediaBrowser.Controller.Entities
bool RequiresRefresh();
- bool EnableForceSaveOnDateModifiedChange { get; }
+ bool EnableRefreshOnDateModifiedChange { get; }
+
+ string PresentationUniqueKey { get; set; }
+
+ string GetPresentationUniqueKey();
+ string CreatePresentationUniqueKey();
+
}
}
diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
index 4effc162e..ba50a1e0d 100644
--- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
+++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
@@ -62,6 +62,19 @@ namespace MediaBrowser.Controller.Entities.Movies
return UnratedItem.Movie;
}
+ protected override IEnumerable<BaseItem> LoadChildren()
+ {
+ var first = LinkedChildren.FirstOrDefault();
+
+ if (first != null && first.Type == LinkedChildType.Shortcut)
+ {
+ return base.LoadChildren();
+ }
+
+ // Save a trip to the database
+ return new List<BaseItem>();
+ }
+
[IgnoreDataMember]
public override bool IsPreSorted
{
diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs
index 8ef0d70bf..4ee140b2b 100644
--- a/MediaBrowser.Controller/Entities/Person.cs
+++ b/MediaBrowser.Controller/Entities/Person.cs
@@ -26,13 +26,9 @@ namespace MediaBrowser.Controller.Entities
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
return list;
}
-
- public override string PresentationUniqueKey
+ public override string CreatePresentationUniqueKey()
{
- get
- {
- return GetUserDataKeys()[0];
- }
+ return GetUserDataKeys()[0];
}
public PersonLookupInfo GetLookupInfo()
diff --git a/MediaBrowser.Controller/Entities/Photo.cs b/MediaBrowser.Controller/Entities/Photo.cs
index 804ea04a5..965616eb5 100644
--- a/MediaBrowser.Controller/Entities/Photo.cs
+++ b/MediaBrowser.Controller/Entities/Photo.cs
@@ -52,7 +52,7 @@ namespace MediaBrowser.Controller.Entities
}
[IgnoreDataMember]
- public override bool EnableForceSaveOnDateModifiedChange
+ public override bool EnableRefreshOnDateModifiedChange
{
get { return true; }
}
diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs
index 762798b55..7e3d6fe8e 100644
--- a/MediaBrowser.Controller/Entities/Studio.cs
+++ b/MediaBrowser.Controller/Entities/Studio.cs
@@ -18,13 +18,9 @@ namespace MediaBrowser.Controller.Entities
list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
return list;
}
-
- public override string PresentationUniqueKey
+ public override string CreatePresentationUniqueKey()
{
- get
- {
- return GetUserDataKeys()[0];
- }
+ return GetUserDataKeys()[0];
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index f6ca19005..c64de399f 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -114,22 +114,18 @@ namespace MediaBrowser.Controller.Entities.TV
}
}
- [IgnoreDataMember]
- public override string PresentationUniqueKey
+ public override string CreatePresentationUniqueKey()
{
- get
+ if (IndexNumber.HasValue)
{
- if (IndexNumber.HasValue)
+ var series = Series;
+ if (series != null)
{
- var series = Series;
- if (series != null)
- {
- return series.PresentationUniqueKey + "-" + (IndexNumber ?? 0).ToString("000");
- }
+ return series.PresentationUniqueKey + "-" + (IndexNumber ?? 0).ToString("000");
}
-
- return base.PresentationUniqueKey;
}
+
+ return base.CreatePresentationUniqueKey();
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index ad35b3d36..f01eddceb 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -96,19 +96,29 @@ namespace MediaBrowser.Controller.Entities.TV
}
}
- [IgnoreDataMember]
- public override string PresentationUniqueKey
+ public override string CreatePresentationUniqueKey()
{
- get
+ var userdatakeys = GetUserDataKeys();
+
+ if (userdatakeys.Count > 1)
{
- var userdatakeys = GetUserDataKeys();
+ return AddLibrariesToPresentationUniqueKey(userdatakeys[0]);
+ }
+ return base.CreatePresentationUniqueKey();
+ }
- if (userdatakeys.Count > 1)
- {
- return userdatakeys[0];
- }
- return base.PresentationUniqueKey;
+ private string AddLibrariesToPresentationUniqueKey(string key)
+ {
+ var folders = LibraryManager.GetCollectionFolders(this)
+ .Select(i => i.Id.ToString("N"))
+ .ToArray();
+
+ if (folders.Length == 0)
+ {
+ return key;
}
+
+ return key + "-" + string.Join("-", folders);
}
private static string GetUniqueSeriesKey(BaseItem series)
@@ -117,7 +127,7 @@ namespace MediaBrowser.Controller.Entities.TV
{
return series.Id.ToString("N");
}
- return series.PresentationUniqueKey;
+ return series.GetPresentationUniqueKey();
}
public override int GetChildCount(User user)
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index 11ed26931..d0f7efa8c 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -1198,7 +1198,7 @@ namespace MediaBrowser.Controller.Entities
{
var user = query.User;
- items = items.DistinctBy(i => i.PresentationUniqueKey, StringComparer.OrdinalIgnoreCase);
+ items = items.DistinctBy(i => i.GetPresentationUniqueKey(), StringComparer.OrdinalIgnoreCase);
if (query.SortBy.Length > 0)
{
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index eba1e466a..830747d3c 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -44,24 +44,23 @@ namespace MediaBrowser.Controller.Entities
}
}
- [IgnoreDataMember]
- public override string PresentationUniqueKey
+ public override string CreatePresentationUniqueKey()
{
- get
+ if (!string.IsNullOrWhiteSpace(PrimaryVersionId))
{
- if (!string.IsNullOrWhiteSpace(PrimaryVersionId))
- {
- return PrimaryVersionId;
- }
-
- return base.PresentationUniqueKey;
+ return PrimaryVersionId;
}
+
+ return base.CreatePresentationUniqueKey();
}
[IgnoreDataMember]
- public override bool EnableForceSaveOnDateModifiedChange
+ public override bool EnableRefreshOnDateModifiedChange
{
- get { return true; }
+ get
+ {
+ return VideoType == VideoType.VideoFile || VideoType == VideoType.Iso;
+ }
}
public int? TotalBitrate { get; set; }
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index ff7f2fe67..edbacb5e7 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -11,6 +11,7 @@ using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Dto;
namespace MediaBrowser.Controller.Library
@@ -32,15 +33,11 @@ namespace MediaBrowser.Controller.Library
/// <summary>
/// Resolves a set of files into a list of BaseItem
/// </summary>
- /// <param name="files">The files.</param>
- /// <param name="directoryService">The directory service.</param>
- /// <param name="parent">The parent.</param>
- /// <param name="collectionType">Type of the collection.</param>
- /// <returns>List{``0}.</returns>
IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files,
IDirectoryService directoryService,
- Folder parent, string
- collectionType = null);
+ Folder parent,
+ LibraryOptions libraryOptions,
+ string collectionType = null);
/// <summary>
/// Gets the root folder.
@@ -397,6 +394,9 @@ namespace MediaBrowser.Controller.Library
/// <returns><c>true</c> if [is audio file] [the specified path]; otherwise, <c>false</c>.</returns>
bool IsAudioFile(string path);
+ bool IsAudioFile(string path, LibraryOptions libraryOptions);
+ bool IsVideoFile(string path, LibraryOptions libraryOptions);
+
/// <summary>
/// Gets the season number from path.
/// </summary>
@@ -453,6 +453,8 @@ namespace MediaBrowser.Controller.Library
/// <returns>IEnumerable&lt;Folder&gt;.</returns>
IEnumerable<Folder> GetCollectionFolders(BaseItem item);
+ LibraryOptions GetLibraryOptions(BaseItem item);
+
/// <summary>
/// Gets the people.
/// </summary>
@@ -551,7 +553,7 @@ namespace MediaBrowser.Controller.Library
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
bool IgnoreFile(FileSystemMetadata file, BaseItem parent);
- void AddVirtualFolder(string name, string collectionType, string[] mediaPaths, bool refreshLibrary);
+ void AddVirtualFolder(string name, string collectionType, string[] mediaPaths, LibraryOptions options, bool refreshLibrary);
void RemoveVirtualFolder(string name, bool refreshLibrary);
void AddMediaPath(string virtualFolderName, string path);
void RemoveMediaPath(string virtualFolderName, string path);
diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs
index ea3199b31..56ec0a213 100644
--- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs
+++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using CommonIO;
+using MediaBrowser.Controller.Configuration;
namespace MediaBrowser.Controller.Library
{
@@ -51,6 +52,13 @@ namespace MediaBrowser.Controller.Library
}
}
+ public LibraryOptions LibraryOptions { get; set; }
+
+ public LibraryOptions GetLibraryOptions()
+ {
+ return LibraryOptions ?? (LibraryOptions = (Parent == null ? new LibraryOptions() : BaseItem.LibraryManager.GetLibraryOptions(Parent)));
+ }
+
/// <summary>
/// Gets or sets the file system dictionary.
/// </summary>
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 0462117cb..e621eafde 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -98,6 +98,7 @@
<Compile Include="Collections\CollectionCreationOptions.cs" />
<Compile Include="Collections\CollectionEvents.cs" />
<Compile Include="Collections\ICollectionManager.cs" />
+ <Compile Include="Configuration\LibraryOptions.cs" />
<Compile Include="Connect\ConnectSupporterSummary.cs" />
<Compile Include="Connect\IConnectManager.cs" />
<Compile Include="Connect\UserLinkResult.cs" />
diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs
index 5ffe3d5da..3e706f1fa 100644
--- a/MediaBrowser.Controller/Playlists/Playlist.cs
+++ b/MediaBrowser.Controller/Playlists/Playlist.cs
@@ -58,6 +58,12 @@ namespace MediaBrowser.Controller.Playlists
return true;
}
+ protected override IEnumerable<BaseItem> LoadChildren()
+ {
+ // Save a trip to the database
+ return new List<BaseItem>();
+ }
+
public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren)
{
return GetPlayableItems(user).Result;
diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs
index 931cc208f..a01d73451 100644
--- a/MediaBrowser.Dlna/DlnaManager.cs
+++ b/MediaBrowser.Dlna/DlnaManager.cs
@@ -73,8 +73,13 @@ namespace MediaBrowser.Dlna
lock (_profiles)
{
var list = _profiles.Values.ToList();
- return list.Select(i => i.Item2).OrderBy(i => i.Name);
+ return list
+ .OrderBy(i => i.Item1.Info.Type == DeviceProfileType.User ? 0 : 1)
+ .ThenBy(i => i.Item1.Info.Name)
+ .Select(i => i.Item2)
+ .ToList();
}
+
}
public DeviceProfile GetDefaultProfile()
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index 08ab99f9b..c8a28e832 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -874,8 +874,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
var mapArg = imageStreamIndex.HasValue ? (" -map 0:v:" + imageStreamIndex.Value.ToString(CultureInfo.InvariantCulture)) : string.Empty;
// Use ffmpeg to sample 100 (we can drop this if required using thumbnail=50 for 50 frames) frames and pick the best thumbnail. Have a fall back just in case.
- var args = useIFrame ? string.Format("-i {0}{3} -threads 1 -v quiet -vframes 1 -vf \"{2},thumbnail=30\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg) :
- string.Format("-i {0}{3} -threads 1 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg);
+ var args = useIFrame ? string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2},thumbnail=30\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg) :
+ string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg);
var probeSize = GetProbeSizeArgument(new[] { inputPath }, protocol);
@@ -980,7 +980,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
FileSystem.CreateDirectory(targetDirectory);
var outputPath = Path.Combine(targetDirectory, filenamePrefix + "%05d.jpg");
- var args = string.Format("-i {0} -threads 1 -v quiet -vf \"{2}\" -f image2 \"{1}\"", inputArgument, outputPath, vf);
+ var args = string.Format("-i {0} -threads 0 -v quiet -vf \"{2}\" -f image2 \"{1}\"", inputArgument, outputPath, vf);
var probeSize = GetProbeSizeArgument(new[] { inputArgument }, protocol);
diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
index f37e223de..9e9bc0780 100644
--- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
+++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
@@ -168,6 +168,12 @@ namespace MediaBrowser.MediaEncoding.Probing
}
ExtractTimestamp(info);
+
+ var stereoMode = GetDictionaryValue(tags, "stereo_mode");
+ if (string.Equals(stereoMode, "left_right", StringComparison.OrdinalIgnoreCase))
+ {
+ info.Video3DFormat = Video3DFormat.FullSideBySide;
+ }
}
return info;
diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs
index 904beb736..2e9f57087 100644
--- a/MediaBrowser.Model/ApiClient/IApiClient.cs
+++ b/MediaBrowser.Model/ApiClient/IApiClient.cs
@@ -302,6 +302,8 @@ namespace MediaBrowser.Model.ApiClient
/// <returns>Task{ItemsResult}.</returns>
Task<ItemsResult> GetSeasonsAsync(SeasonQuery query, CancellationToken cancellationToken = default(CancellationToken));
+ Task<PluginSecurityInfo> GetRegistrationInfo();
+
/// <summary>
/// Queries for items
/// </summary>
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index 58b74ba64..303ba1acf 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -180,8 +180,6 @@ namespace MediaBrowser.Model.Configuration
public NameValuePair[] ContentTypes { get; set; }
- public bool EnableAudioArchiveFiles { get; set; }
- public bool EnableVideoArchiveFiles { get; set; }
public int RemoteClientBitrateLimit { get; set; }
public AutoOnOff EnableLibraryMonitor { get; set; }
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index ac942d1a7..0483a74ed 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -149,7 +149,7 @@ namespace MediaBrowser.Providers.Manager
if (file != null)
{
var fileLastWriteTime = file.LastWriteTimeUtc;
- if (item.EnableForceSaveOnDateModifiedChange && fileLastWriteTime != item.DateModified)
+ if (item.EnableRefreshOnDateModifiedChange && fileLastWriteTime != item.DateModified)
{
Logger.Debug("Date modified for {0}. Old date {1} new date {2} Id {3}", item.Path, item.DateModified, fileLastWriteTime, item.Id);
requiresRefresh = true;
@@ -284,6 +284,13 @@ namespace MediaBrowser.Providers.Manager
updateType |= SaveCumulativeRunTimeTicks(item, isFullRefresh, currentUpdateType);
updateType |= SaveDateLastMediaAdded(item, isFullRefresh, currentUpdateType);
+ var presentationUniqueKey = item.CreatePresentationUniqueKey();
+ if (!string.Equals(item.PresentationUniqueKey, presentationUniqueKey, StringComparison.Ordinal))
+ {
+ item.PresentationUniqueKey = presentationUniqueKey;
+ updateType |= ItemUpdateType.MetadataImport;
+ }
+
return updateType;
}
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
index 11280cff2..0df8b6c4b 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
@@ -171,10 +171,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))
{
- return true;
+ var file = directoryService.GetFile(item.Path);
+ if (file != null && file.LastWriteTimeUtc != item.DateModified)
+ {
+ return true;
+ }
}
if (item.SupportsLocalMetadata)
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
index e1ab61cbb..c20823535 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
@@ -231,6 +231,8 @@ namespace MediaBrowser.Providers.MediaInfo
video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle);
video.Timestamp = mediaInfo.Timestamp;
+ video.Video3DFormat = video.Video3DFormat ?? mediaInfo.Video3DFormat;
+
await _itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken).ConfigureAwait(false);
if (options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh ||
diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
index fb08f00c1..280e92beb 100644
--- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
@@ -194,10 +194,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)
{
- return true;
+ var file = directoryService.GetFile(item.Path);
+ if (file != null && file.LastWriteTimeUtc != item.DateModified)
+ {
+ return true;
+ }
}
return false;
diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs
index addab3918..cf04a1418 100644
--- a/MediaBrowser.Providers/TV/SeasonMetadataService.cs
+++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs
@@ -35,26 +35,17 @@ namespace MediaBrowser.Providers.TV
updateType |= SaveIsVirtualItem(item, episodes);
}
- if (updateType <= ItemUpdateType.None)
+ if (!string.Equals(item.SeriesName, item.FindSeriesName(), StringComparison.Ordinal))
{
- if (!string.Equals(item.SeriesName, item.FindSeriesName(), StringComparison.Ordinal))
- {
- updateType |= ItemUpdateType.MetadataImport;
- }
+ updateType |= ItemUpdateType.MetadataImport;
}
- if (updateType <= ItemUpdateType.None)
+ if (!string.Equals(item.SeriesSortName, item.FindSeriesSortName(), StringComparison.Ordinal))
{
- if (!string.Equals(item.SeriesSortName, item.FindSeriesSortName(), StringComparison.Ordinal))
- {
- updateType |= ItemUpdateType.MetadataImport;
- }
+ updateType |= ItemUpdateType.MetadataImport;
}
- if (updateType <= ItemUpdateType.None)
+ if (item.SeriesId != item.FindSeriesId())
{
- if (item.SeriesId != item.FindSeriesId())
- {
- updateType |= ItemUpdateType.MetadataImport;
- }
+ updateType |= ItemUpdateType.MetadataImport;
}
return updateType;
diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs
index c0a2a5eb3..194904320 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs
@@ -275,7 +275,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
/// <returns>System.Object.</returns>
private object GetCachedResult(IRequest requestContext, IDictionary<string, string> responseHeaders, Guid cacheKey, string cacheKeyString, DateTime? lastDateModified, TimeSpan? cacheDuration, string contentType)
{
- responseHeaders["ETag"] = cacheKeyString;
+ responseHeaders["ETag"] = string.Format("\"{0}\"", cacheKeyString);
if (IsNotModified(requestContext, cacheKey, lastDateModified, cacheDuration))
{
diff --git a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs
index 5c72ac9c7..2f4605c5c 100644
--- a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs
+++ b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs
@@ -61,6 +61,11 @@ namespace MediaBrowser.Server.Implementations.IO
public void RestartTimer()
{
+ if (_disposed)
+ {
+ return;
+ }
+
lock (_timerLock)
{
if (_timer == null)
@@ -286,8 +291,10 @@ namespace MediaBrowser.Server.Implementations.IO
}
}
+ private bool _disposed;
public void Dispose()
{
+ _disposed = true;
DisposeTimer();
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index 055fde504..b00303f29 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -556,7 +556,12 @@ namespace MediaBrowser.Server.Implementations.Library
return ResolvePath(fileInfo, new DirectoryService(_logger, _fileSystem), null, parent);
}
- private BaseItem ResolvePath(FileSystemMetadata fileInfo, IDirectoryService directoryService, IItemResolver[] resolvers, Folder parent = null, string collectionType = null)
+ private BaseItem ResolvePath(FileSystemMetadata fileInfo,
+ IDirectoryService directoryService,
+ IItemResolver[] resolvers,
+ Folder parent = null,
+ string collectionType = null,
+ LibraryOptions libraryOptions = null)
{
if (fileInfo == null)
{
@@ -575,7 +580,8 @@ namespace MediaBrowser.Server.Implementations.Library
Parent = parent,
Path = fullPath,
FileInfo = fileInfo,
- CollectionType = collectionType
+ CollectionType = collectionType,
+ LibraryOptions = libraryOptions
};
// Return null if ignore rules deem that we should do so
@@ -653,12 +659,17 @@ namespace MediaBrowser.Server.Implementations.Library
return !args.ContainsFileSystemEntryByName(".ignore");
}
- public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, Folder parent, string collectionType)
+ public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, Folder parent, LibraryOptions libraryOptions, string collectionType)
{
- return ResolvePaths(files, directoryService, parent, collectionType, EntityResolvers);
+ return ResolvePaths(files, directoryService, parent, libraryOptions, collectionType, EntityResolvers);
}
- public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, Folder parent, string collectionType, IItemResolver[] resolvers)
+ public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files,
+ IDirectoryService directoryService,
+ Folder parent,
+ LibraryOptions libraryOptions,
+ string collectionType,
+ IItemResolver[] resolvers)
{
var fileList = files.Where(i => !IgnoreFile(i, parent)).ToList();
@@ -679,22 +690,27 @@ namespace MediaBrowser.Server.Implementations.Library
{
ResolverHelper.SetInitialItemValues(item, parent, _fileSystem, this, directoryService);
}
- items.AddRange(ResolveFileList(result.ExtraFiles, directoryService, parent, collectionType, resolvers));
+ items.AddRange(ResolveFileList(result.ExtraFiles, directoryService, parent, collectionType, resolvers, libraryOptions));
return items;
}
}
}
- return ResolveFileList(fileList, directoryService, parent, collectionType, resolvers);
+ return ResolveFileList(fileList, directoryService, parent, collectionType, resolvers, libraryOptions);
}
- private IEnumerable<BaseItem> ResolveFileList(IEnumerable<FileSystemMetadata> fileList, IDirectoryService directoryService, Folder parent, string collectionType, IItemResolver[] resolvers)
+ private IEnumerable<BaseItem> ResolveFileList(IEnumerable<FileSystemMetadata> fileList,
+ IDirectoryService directoryService,
+ Folder parent,
+ string collectionType,
+ IItemResolver[] resolvers,
+ LibraryOptions libraryOptions)
{
return fileList.Select(f =>
{
try
{
- return ResolvePath(f, directoryService, resolvers, parent, collectionType);
+ return ResolvePath(f, directoryService, resolvers, parent, collectionType, libraryOptions);
}
catch (Exception ex)
{
@@ -1891,6 +1907,15 @@ namespace MediaBrowser.Server.Implementations.Library
.Where(i => string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path, StringComparer.OrdinalIgnoreCase));
}
+ public LibraryOptions GetLibraryOptions(BaseItem item)
+ {
+ var collectionFolder = GetCollectionFolders(item)
+ .OfType<CollectionFolder>()
+ .FirstOrDefault();
+
+ return collectionFolder == null ? new LibraryOptions() : collectionFolder.GetLibraryOptions();
+ }
+
public string GetContentType(BaseItem item)
{
string configuredContentType = GetConfiguredContentType(item, false);
@@ -2242,18 +2267,28 @@ namespace MediaBrowser.Server.Implementations.Library
return item;
}
- public bool IsVideoFile(string path)
+ public bool IsVideoFile(string path, LibraryOptions libraryOptions)
{
- var resolver = new VideoResolver(GetNamingOptions(), new PatternsLogger());
+ var resolver = new VideoResolver(GetNamingOptions(libraryOptions), new PatternsLogger());
return resolver.IsVideoFile(path);
}
- public bool IsAudioFile(string path)
+ public bool IsVideoFile(string path)
+ {
+ return IsVideoFile(path, new LibraryOptions());
+ }
+
+ public bool IsAudioFile(string path, LibraryOptions libraryOptions)
{
- var parser = new AudioFileParser(GetNamingOptions());
+ var parser = new AudioFileParser(GetNamingOptions(libraryOptions));
return parser.IsAudioFile(path);
}
+ public bool IsAudioFile(string path)
+ {
+ return IsAudioFile(path, new LibraryOptions());
+ }
+
public int? GetSeasonNumberFromPath(string path)
{
return new SeasonPathParser(GetNamingOptions(), new RegexProvider()).Parse(path, true, true).SeasonNumber;
@@ -2380,19 +2415,24 @@ namespace MediaBrowser.Server.Implementations.Library
public NamingOptions GetNamingOptions()
{
+ return GetNamingOptions(new LibraryOptions());
+ }
+
+ public NamingOptions GetNamingOptions(LibraryOptions libraryOptions)
+ {
var options = new ExtendedNamingOptions();
// These cause apps to have problems
options.AudioFileExtensions.Remove(".m3u");
options.AudioFileExtensions.Remove(".wpl");
- if (!ConfigurationManager.Configuration.EnableAudioArchiveFiles)
+ if (!libraryOptions.EnableAudioArchiveFiles)
{
options.AudioFileExtensions.Remove(".rar");
options.AudioFileExtensions.Remove(".zip");
}
- if (!ConfigurationManager.Configuration.EnableVideoArchiveFiles)
+ if (!libraryOptions.EnableVideoArchiveFiles)
{
options.VideoFileExtensions.Remove(".rar");
options.VideoFileExtensions.Remove(".zip");
@@ -2443,7 +2483,7 @@ namespace MediaBrowser.Server.Implementations.Library
new GenericVideoResolver<Trailer>(this)
};
- return ResolvePaths(files, directoryService, null, null, resolvers)
+ return ResolvePaths(files, directoryService, null, new LibraryOptions(), null, resolvers)
.OfType<Trailer>()
.Select(video =>
{
@@ -2487,7 +2527,7 @@ namespace MediaBrowser.Server.Implementations.Library
files.AddRange(currentVideo.Extras.Where(i => !string.Equals(i.ExtraType, "trailer", StringComparison.OrdinalIgnoreCase)).Select(i => _fileSystem.GetFileInfo(i.Path)));
}
- return ResolvePaths(files, directoryService, null, null)
+ return ResolvePaths(files, directoryService, null, new LibraryOptions(), null)
.OfType<Video>()
.Select(video =>
{
@@ -2665,7 +2705,7 @@ namespace MediaBrowser.Server.Implementations.Library
throw new InvalidOperationException();
}
- public void AddVirtualFolder(string name, string collectionType, string[] mediaPaths, bool refreshLibrary)
+ public void AddVirtualFolder(string name, string collectionType, string[] mediaPaths, LibraryOptions options, bool refreshLibrary)
{
if (string.IsNullOrWhiteSpace(name))
{
@@ -2708,6 +2748,8 @@ namespace MediaBrowser.Server.Implementations.Library
}
}
+ CollectionFolder.SaveLibraryOptions(virtualFolderPath, options);
+
if (mediaPaths != null)
{
foreach (var path in mediaPaths)
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
index b4cda39cd..039a17100 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
@@ -37,14 +37,16 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
if (!args.IsDirectory)
{
- if (_libraryManager.IsAudioFile(args.Path))
+ var libraryOptions = args.GetLibraryOptions();
+
+ if (_libraryManager.IsAudioFile(args.Path, libraryOptions))
{
var collectionType = args.GetCollectionType();
var isMixed = string.IsNullOrWhiteSpace(collectionType);
// For conflicting extensions, give priority to videos
- if (isMixed && _libraryManager.IsVideoFile(args.Path))
+ if (isMixed && _libraryManager.IsVideoFile(args.Path, libraryOptions))
{
return null;
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
index 9f8293cb5..546f64d3c 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
@@ -10,6 +10,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using CommonIO;
+using MediaBrowser.Controller.Configuration;
namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
{
@@ -72,12 +73,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
/// <summary>
/// Determine if the supplied file data points to a music album
/// </summary>
- /// <param name="path">The path.</param>
- /// <param name="directoryService">The directory service.</param>
- /// <returns><c>true</c> if [is music album] [the specified data]; otherwise, <c>false</c>.</returns>
- public bool IsMusicAlbum(string path, IDirectoryService directoryService)
+ public bool IsMusicAlbum(string path, IDirectoryService directoryService, LibraryOptions libraryOptions)
{
- return ContainsMusic(directoryService.GetFileSystemEntries(path), true, directoryService, _logger, _fileSystem, _libraryManager);
+ return ContainsMusic(directoryService.GetFileSystemEntries(path), true, directoryService, _logger, _fileSystem, libraryOptions, _libraryManager);
}
/// <summary>
@@ -91,7 +89,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
if (args.IsDirectory)
{
//if (args.Parent is MusicArtist) return true; //saves us from testing children twice
- if (ContainsMusic(args.FileSystemChildren, true, args.DirectoryService, _logger, _fileSystem, _libraryManager)) return true;
+ if (ContainsMusic(args.FileSystemChildren, true, args.DirectoryService, _logger, _fileSystem, args.GetLibraryOptions(), _libraryManager)) return true;
}
return false;
@@ -100,18 +98,12 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
/// <summary>
/// Determine if the supplied list contains what we should consider music
/// </summary>
- /// <param name="list">The list.</param>
- /// <param name="allowSubfolders">if set to <c>true</c> [allow subfolders].</param>
- /// <param name="directoryService">The directory service.</param>
- /// <param name="logger">The logger.</param>
- /// <param name="fileSystem">The file system.</param>
- /// <param name="libraryManager">The library manager.</param>
- /// <returns><c>true</c> if the specified list contains music; otherwise, <c>false</c>.</returns>
private bool ContainsMusic(IEnumerable<FileSystemMetadata> list,
bool allowSubfolders,
IDirectoryService directoryService,
ILogger logger,
IFileSystem fileSystem,
+ LibraryOptions libraryOptions,
ILibraryManager libraryManager)
{
var discSubfolderCount = 0;
@@ -124,11 +116,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
if (allowSubfolders)
{
var path = fileSystemInfo.FullName;
- var isMultiDisc = IsMultiDiscFolder(path);
+ var isMultiDisc = IsMultiDiscFolder(path, libraryOptions);
if (isMultiDisc)
{
- var hasMusic = ContainsMusic(directoryService.GetFileSystemEntries(path), false, directoryService, logger, fileSystem, libraryManager);
+ var hasMusic = ContainsMusic(directoryService.GetFileSystemEntries(path), false, directoryService, logger, fileSystem, libraryOptions, libraryManager);
if (hasMusic)
{
@@ -138,7 +130,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
}
else
{
- var hasMusic = ContainsMusic(directoryService.GetFileSystemEntries(path), false, directoryService, logger, fileSystem, libraryManager);
+ var hasMusic = ContainsMusic(directoryService.GetFileSystemEntries(path), false, directoryService, logger, fileSystem, libraryOptions, libraryManager);
if (hasMusic)
{
@@ -151,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
var fullName = fileSystemInfo.FullName;
- if (libraryManager.IsAudioFile(fullName))
+ if (libraryManager.IsAudioFile(fullName, libraryOptions))
{
return true;
}
@@ -165,9 +157,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
return discSubfolderCount > 0;
}
- private bool IsMultiDiscFolder(string path)
+ private bool IsMultiDiscFolder(string path, LibraryOptions libraryOptions)
{
- var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
+ var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(libraryOptions);
var parser = new AlbumParser(namingOptions, new PatternsLogger());
var result = parser.ParseMultiPart(path);
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
index e3c991e7e..e819af06f 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
@@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
var albumResolver = new MusicAlbumResolver(_logger, _fileSystem, _libraryManager);
// If we contain an album assume we are an artist folder
- return args.FileSystemChildren.Where(i => (i.Attributes & FileAttributes.Directory) == FileAttributes.Directory).Any(i => albumResolver.IsMusicAlbum(i.FullName, directoryService)) ? new MusicArtist() : null;
+ return args.FileSystemChildren.Where(i => (i.Attributes & FileAttributes.Directory) == FileAttributes.Directory).Any(i => albumResolver.IsMusicAlbum(i.FullName, directoryService, args.GetLibraryOptions())) ? new MusicArtist() : null;
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
index 703a33856..d0042a990 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
@@ -133,7 +133,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
return null;
}
- if (LibraryManager.IsVideoFile(args.Path) || videoInfo.IsStub)
+ if (LibraryManager.IsVideoFile(args.Path, args.GetLibraryOptions()) || videoInfo.IsStub)
{
var path = args.Path;
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs
index 9dd30edde..09a9a3b4e 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs
@@ -6,6 +6,7 @@ using System;
using System.IO;
using System.Linq;
using CommonIO;
+using MediaBrowser.Controller.Configuration;
namespace MediaBrowser.Server.Implementations.Library.Resolvers
{
@@ -40,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
var filename = Path.GetFileNameWithoutExtension(args.Path);
// Make sure the image doesn't belong to a video file
- if (args.DirectoryService.GetFiles(Path.GetDirectoryName(args.Path)).Any(i => IsOwnedByMedia(i, filename)))
+ if (args.DirectoryService.GetFiles(Path.GetDirectoryName(args.Path)).Any(i => IsOwnedByMedia(args.GetLibraryOptions(), i, filename)))
{
return null;
}
@@ -56,9 +57,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
return null;
}
- private bool IsOwnedByMedia(FileSystemMetadata file, string imageFilename)
+ private bool IsOwnedByMedia(LibraryOptions libraryOptions, FileSystemMetadata file, string imageFilename)
{
- if (_libraryManager.IsVideoFile(file.FullName) && imageFilename.StartsWith(Path.GetFileNameWithoutExtension(file.Name), StringComparison.OrdinalIgnoreCase))
+ if (_libraryManager.IsVideoFile(file.FullName, libraryOptions) && imageFilename.StartsWith(Path.GetFileNameWithoutExtension(file.Name), StringComparison.OrdinalIgnoreCase))
{
return true;
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
index 45ba2ddbb..f1bbc1f32 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
@@ -12,6 +12,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using CommonIO;
+using MediaBrowser.Controller.Configuration;
namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
{
@@ -83,7 +84,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
{
return null;
}
- if (IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager, false))
+ if (IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager, args.GetLibraryOptions(), false))
{
return new Series
{
@@ -104,6 +105,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
IFileSystem fileSystem,
ILogger logger,
ILibraryManager libraryManager,
+ LibraryOptions libraryOptions,
bool isTvContentType)
{
foreach (var child in fileSystemChildren)
@@ -134,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
else
{
string fullName = child.FullName;
- if (libraryManager.IsVideoFile(fullName))
+ if (libraryManager.IsVideoFile(fullName, libraryOptions))
{
if (isTvContentType)
{
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs
index 191c7ef28..d90b9615b 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs
@@ -126,7 +126,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
var item = _libraryManager.GetPerson(person.Key);
var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview);
- var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 60;
+ var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 30;
var defaultMetadataRefreshMode = performFullRefresh
? MetadataRefreshMode.FullRefresh
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index ee8ab7c25..4c9b2a4d9 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -143,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
try
{
- _libraryManager.AddVirtualFolder(recordingFolder.Name, recordingFolder.CollectionType, pathsToCreate.ToArray(), true);
+ _libraryManager.AddVirtualFolder(recordingFolder.Name, recordingFolder.CollectionType, pathsToCreate.ToArray(), new LibraryOptions(), true);
}
catch (Exception ex)
{
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index b4f8245ed..bbb36b46e 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -412,7 +412,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
"SeasonName",
"SeasonId",
"SeriesId",
- "SeriesSortName"
+ "SeriesSortName",
+ "PresentationUniqueKey"
};
private readonly string[] _mediaStreamSaveColumns =
@@ -918,7 +919,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
_saveItemCommand.GetParameter(index++).Value = GetCleanValue(item.Name);
}
- _saveItemCommand.GetParameter(index++).Value = item.PresentationUniqueKey;
+ _saveItemCommand.GetParameter(index++).Value = item.GetPresentationUniqueKey();
_saveItemCommand.GetParameter(index++).Value = item.SlugName;
_saveItemCommand.GetParameter(index++).Value = item.OriginalTitle;
@@ -1454,6 +1455,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
index++;
+ if (!reader.IsDBNull(index))
+ {
+ item.PresentationUniqueKey = reader.GetString(index);
+ }
+ index++;
+
return item;
}
@@ -2230,7 +2237,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
if (string.Equals(name, ItemSortBy.OfficialRating, StringComparison.OrdinalIgnoreCase))
{
- return new Tuple<string, bool>("ParentalRatingValue", false);
+ return new Tuple<string, bool>("InheritedParentalRatingValue", false);
}
if (string.Equals(name, ItemSortBy.Studio, StringComparison.OrdinalIgnoreCase))
{
@@ -3473,7 +3480,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
using (var cmd = _connection.CreateCommand())
{
- cmd.CommandText = "select Guid,InheritedParentalRatingValue,(select Max(ParentalRatingValue, (select COALESCE(MAX(ParentalRatingValue),0) from TypedBaseItems where guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid)))) as NewInheritedParentalRatingValue from typedbaseitems as Outer where InheritedParentalRatingValue <> NewInheritedParentalRatingValue";
+ cmd.CommandText = "select Guid,InheritedParentalRatingValue,(select Max(InheritedParentalRatingValue, (select COALESCE(MAX(InheritedParentalRatingValue),0) from TypedBaseItems where guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid)))) as NewInheritedParentalRatingValue from typedbaseitems as Outer where InheritedParentalRatingValue <> NewInheritedParentalRatingValue";
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
{
@@ -4034,7 +4041,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
? (CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)
: CommandBehavior.SequentialAccess;
- Logger.Debug("GetItemValues: " + cmd.CommandText);
+ //Logger.Debug("GetItemValues: " + cmd.CommandText);
using (var reader = cmd.ExecuteReader(commandBehavior))
{
diff --git a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs
index 20324215b..ff0e4a0e0 100644
--- a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs
+++ b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs
@@ -22,7 +22,7 @@ namespace MediaBrowser.Server.Implementations.Playlists
protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
{
- return GetRecursiveChildren(i => i is Playlist);
+ return base.GetEligibleChildrenForRecursiveChildren(user).OfType<Playlist>();
}
public override bool IsHidden
diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs
index ddc1de9cd..03e8a9178 100644
--- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs
+++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs
@@ -152,7 +152,7 @@ namespace MediaBrowser.Server.Implementations.TV
{
return series.Id.ToString("N");
}
- return series.PresentationUniqueKey;
+ return series.GetPresentationUniqueKey();
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs
index ea4da19b2..3c75c8a48 100644
--- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs
+++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs
@@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.UserViews
User = view.UserId.HasValue ? _userManager.GetUserById(view.UserId.Value) : null,
CollapseBoxSetItems = false,
Recursive = recursive,
- ExcludeItemTypes = new[] { "UserView", "CollectionFolder" }
+ ExcludeItemTypes = new[] { "UserView", "CollectionFolder", "Person" },
}).ConfigureAwait(false);
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index ce99f0a24..74438abbc 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -765,6 +765,7 @@ namespace MediaBrowser.Server.Startup.Common
UserView.PlaylistManager = PlaylistManager;
BaseItem.CollectionManager = CollectionManager;
BaseItem.MediaSourceManager = MediaSourceManager;
+ CollectionFolder.XmlSerializer = XmlSerializer;
}
/// <summary>
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index 34ad32111..4e4a98060 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -58,6 +58,11 @@ namespace MediaBrowser.WebDashboard.Api
{
}
+ [Route("/web/staticfiles", "GET")]
+ public class GetCacheFiles
+ {
+ }
+
/// <summary>
/// Class GetDashboardResource
/// </summary>
@@ -140,6 +145,27 @@ namespace MediaBrowser.WebDashboard.Api
return ResultFactory.GetStaticResult(Request, page.Plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml("dummy.html", page.GetHtmlStream(), null, _appHost.ApplicationVersion.ToString(), null, false));
}
+ public object Get(GetCacheFiles request)
+ {
+ var allFiles = GetCacheFileList();
+
+ return ResultFactory.GetOptimizedResult(Request, _jsonSerializer.SerializeToString(allFiles));
+ }
+
+ private List<string> GetCacheFileList()
+ {
+ var creator = GetPackageCreator();
+ var directory = creator.DashboardUIPath;
+
+ var skipExtensions = GetUndeployedExtensions();
+
+ return
+ Directory.GetFiles(directory, "*", SearchOption.AllDirectories)
+ .Where(i => !skipExtensions.Contains(Path.GetExtension(i) ?? string.Empty, StringComparer.OrdinalIgnoreCase))
+ .Select(i => i.Replace(directory, string.Empty, StringComparison.OrdinalIgnoreCase).Replace("\\", "/").TrimStart('/') + "?v=" + _appHost.ApplicationVersion.ToString())
+ .ToList();
+ }
+
/// <summary>
/// Gets the specified request.
/// </summary>
@@ -274,6 +300,21 @@ namespace MediaBrowser.WebDashboard.Api
return new PackageCreator(_fileSystem, _localization, Logger, _serverConfigurationManager, _jsonSerializer);
}
+ private List<string> GetUndeployedExtensions()
+ {
+ var list = new List<string>();
+
+ list.Add(".log");
+ list.Add(".txt");
+ list.Add(".map");
+ list.Add(".md");
+ list.Add(".gz");
+ list.Add(".bat");
+ list.Add(".sh");
+
+ return list;
+ }
+
public async Task<object> Get(GetDashboardPackage request)
{
var path = Path.Combine(_serverConfigurationManager.ApplicationPaths.ProgramDataPath,
@@ -296,12 +337,9 @@ namespace MediaBrowser.WebDashboard.Api
var appVersion = _appHost.ApplicationVersion.ToString();
- var mode = request.Mode;
+ File.WriteAllText(Path.Combine(path, "staticfiles"), _jsonSerializer.SerializeToString(GetCacheFileList()));
- if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase))
- {
- _fileSystem.DeleteFile(Path.Combine(path, "scripts", "registrationservices.js"));
- }
+ var mode = request.Mode;
// Try to trim the output size a bit
var bowerPath = Path.Combine(path, "bower_components");
@@ -313,14 +351,9 @@ namespace MediaBrowser.WebDashboard.Api
//bowerPath = versionedBowerPath;
}
- DeleteFilesByExtension(bowerPath, ".log");
- DeleteFilesByExtension(bowerPath, ".txt");
- DeleteFilesByExtension(bowerPath, ".map");
- DeleteFilesByExtension(bowerPath, ".md");
+ GetUndeployedExtensions().ForEach(i => DeleteFilesByExtension(bowerPath, i));
+
DeleteFilesByExtension(bowerPath, ".json", "strings\\");
- DeleteFilesByExtension(bowerPath, ".gz");
- DeleteFilesByExtension(bowerPath, ".bat");
- DeleteFilesByExtension(bowerPath, ".sh");
DeleteFilesByName(bowerPath, "copying", true);
DeleteFilesByName(bowerPath, "license", true);
DeleteFilesByName(bowerPath, "license-mit", true);
@@ -359,13 +392,11 @@ namespace MediaBrowser.WebDashboard.Api
//DeleteFoldersByName(Path.Combine(bowerPath, "Sortable"), "meteor");
//DeleteFoldersByName(Path.Combine(bowerPath, "Sortable"), "st");
//DeleteFoldersByName(Path.Combine(bowerPath, "Swiper"), "src");
-
+
if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase))
{
// Delete things that are unneeded in an attempt to keep the output as trim as possible
_fileSystem.DeleteDirectory(Path.Combine(path, "css", "images", "tour"), true);
-
- _fileSystem.DeleteFile(Path.Combine(path, "thirdparty", "jquerymobile-1.4.5", "jquery.mobile-1.4.5.min.map"));
}
else
{
diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
index b7b1f1dfd..c5af1cee7 100644
--- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs
+++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
@@ -372,12 +372,12 @@ namespace MediaBrowser.WebDashboard.Api
sb.Append("<meta property=\"fb:app_id\" content=\"1618309211750238\">");
// http://developer.apple.com/library/ios/#DOCUMENTATION/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html
- sb.Append("<link rel=\"apple-touch-icon\" href=\"css/images/touchicon.png\">");
- sb.Append("<link rel=\"apple-touch-icon\" sizes=\"72x72\" href=\"css/images/touchicon72.png\">");
- sb.Append("<link rel=\"apple-touch-icon\" sizes=\"114x114\" href=\"css/images/touchicon114.png\">");
+ sb.Append("<link rel=\"apple-touch-icon\" href=\"touchicon.png\">");
+ sb.Append("<link rel=\"apple-touch-icon\" sizes=\"72x72\" href=\"touchicon72.png\">");
+ sb.Append("<link rel=\"apple-touch-icon\" sizes=\"114x114\" href=\"touchicon114.png\">");
sb.Append("<link rel=\"apple-touch-startup-image\" href=\"css/images/iossplash.png\">");
sb.Append("<link rel=\"shortcut icon\" href=\"css/images/favicon.ico\">");
- sb.Append("<meta name=\"msapplication-TileImage\" content=\"css/images/touchicon144.png\">");
+ sb.Append("<meta name=\"msapplication-TileImage\" content=\"touchicon144.png\">");
sb.Append("<meta name=\"msapplication-TileColor\" content=\"#333333\">");
sb.Append("<meta name=\"theme-color\" content=\"#43A047\">");
@@ -431,7 +431,7 @@ namespace MediaBrowser.WebDashboard.Api
var files = new List<string>();
- files.Add("bower_components/requirejs/require.js");
+ files.Add("bower_components/requirejs/require.js" + versionString);
files.Add("scripts/site.js" + versionString);
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index cc064dc81..f1b234b90 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -143,6 +143,12 @@
<Content Include="dashboard-ui\components\guestinviter\guestinviter.template.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\components\libraryoptionseditor\libraryoptionseditor.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="dashboard-ui\components\libraryoptionseditor\libraryoptionseditor.template.html">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\components\navdrawer\navdrawer.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -233,10 +239,7 @@
<Content Include="dashboard-ui\css\images\empty.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\css\images\logo536.png">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- <Content Include="dashboard-ui\css\images\touchicon144.png">
+ <Content Include="dashboard-ui\touchicon144.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\tour\admin\help.png">
@@ -1196,13 +1199,13 @@
</Content>
</ItemGroup>
<ItemGroup>
- <Content Include="dashboard-ui\css\images\touchicon.png">
+ <Content Include="dashboard-ui\touchicon.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\css\images\touchicon114.png">
+ <Content Include="dashboard-ui\touchicon114.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\css\images\touchicon72.png">
+ <Content Include="dashboard-ui\touchicon72.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>