From 00b515099966ed416b98789d72b955384224c27c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 5 Jan 2015 01:00:13 -0500 Subject: [PATCH 01/11] re-enable sync --- .../Encoder/AudioEncoder.cs | 5 ++ .../Encoder/BaseEncoder.cs | 68 ++++++++++++++++--- .../Encoder/EncodingJob.cs | 7 ++ .../Encoder/VideoEncoder.cs | 5 ++ .../Sync/SyncJobProcessor.cs | 60 +++++++++++++--- .../Sync/SyncScheduledTask.cs | 2 +- SharedVersion.cs | 4 +- 7 files changed, 128 insertions(+), 23 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs index 7054accfad..52221d349e 100644 --- a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs @@ -82,5 +82,10 @@ namespace MediaBrowser.MediaEncoding.Encoder return null; } + + protected override bool IsVideoEncoder + { + get { return false; } + } } } diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index a350d05774..3c30d7cd80 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -142,6 +142,8 @@ namespace MediaBrowser.MediaEncoding.Encoder throw; } + cancellationToken.Register(() => Cancel(process, encodingJob)); + // MUST read both stdout and stderr asynchronously or a deadlock may occurr process.BeginOutputReadLine(); @@ -157,6 +159,16 @@ namespace MediaBrowser.MediaEncoding.Encoder return encodingJob; } + private void Cancel(Process process, EncodingJob job) + { + Logger.Info("Killing ffmpeg process for {0}", job.OutputFilePath); + + //process.Kill(); + process.StandardInput.WriteLine("q"); + + job.IsCancelled = true; + } + /// /// Processes the exited. /// @@ -169,25 +181,53 @@ namespace MediaBrowser.MediaEncoding.Encoder Logger.Debug("Disposing stream resources"); job.Dispose(); + var isSuccesful = false; + try { - Logger.Info("FFMpeg exited with code {0}", process.ExitCode); + var exitCode = process.ExitCode; + Logger.Info("FFMpeg exited with code {0}", exitCode); + + isSuccesful = exitCode == 0; + } + catch + { + Logger.Error("FFMpeg exited with an error."); + } + if (isSuccesful && !job.IsCancelled) + { + job.TaskCompletionSource.TrySetResult(true); + } + else if (job.IsCancelled) + { try { - job.TaskCompletionSource.TrySetResult(true); + DeleteFiles(job); + } + catch + { + } + try + { + job.TaskCompletionSource.TrySetException(new OperationCanceledException()); } catch { } } - catch + else { - Logger.Error("FFMpeg exited with an error."); - try { - job.TaskCompletionSource.TrySetException(new ApplicationException()); + DeleteFiles(job); + } + catch + { + } + try + { + job.TaskCompletionSource.TrySetException(new ApplicationException("Encoding failed")); } catch { @@ -206,6 +246,11 @@ namespace MediaBrowser.MediaEncoding.Encoder //} } + protected virtual void DeleteFiles(EncodingJob job) + { + File.Delete(job.OutputFilePath); + } + private void OnTranscodeBeginning(EncodingJob job) { job.ReportTranscodingProgress(null, null, null, null); @@ -219,10 +264,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - protected virtual bool IsVideoEncoder - { - get { return false; } - } + protected abstract bool IsVideoEncoder { get; } protected virtual string GetWorkingDirectory(EncodingJobOptions options) { @@ -263,6 +305,12 @@ namespace MediaBrowser.MediaEncoding.Encoder /// System.Int32. protected int GetNumberOfThreads(EncodingJob job, bool isWebm) { + // Only need one thread for sync + if (job.Options.Context == EncodingContext.Static) + { + return 1; + } + if (isWebm) { // Recommended per docs diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs index 40ca08c405..c8d121eead 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs @@ -18,6 +18,7 @@ namespace MediaBrowser.MediaEncoding.Encoder public class EncodingJob : IDisposable { public bool HasExited { get; internal set; } + public bool IsCancelled { get; internal set; } public Stream LogFileStream { get; set; } public IProgress Progress { get; set; } @@ -399,6 +400,12 @@ namespace MediaBrowser.MediaEncoding.Encoder // job.Framerate = framerate; + if (!percentComplete.HasValue && ticks.HasValue && RunTimeTicks.HasValue) + { + var pct = ticks.Value/RunTimeTicks.Value; + percentComplete = pct*100; + } + if (percentComplete.HasValue) { Progress.Report(percentComplete.Value); diff --git a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs index 36406e3a3f..941649addc 100644 --- a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs @@ -173,5 +173,10 @@ namespace MediaBrowser.MediaEncoding.Encoder return null; } + + protected override bool IsVideoEncoder + { + get { return true; } + } } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 7a363c54a9..b09bfe91fb 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Entities; +using MediaBrowser.Common.Progress; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; @@ -337,7 +338,9 @@ namespace MediaBrowser.Server.Implementations.Sync cancellationToken.ThrowIfCancellationRequested(); - await ProcessJobItem(item, cancellationToken).ConfigureAwait(false); + var innerProgress = new ActionableProgress(); + + await ProcessJobItem(item, innerProgress, cancellationToken).ConfigureAwait(false); var job = _syncRepo.GetJob(item.JobId); await UpdateJobStatus(job).ConfigureAwait(false); @@ -346,7 +349,7 @@ namespace MediaBrowser.Server.Implementations.Sync } } - private async Task ProcessJobItem(SyncJobItem jobItem, CancellationToken cancellationToken) + private async Task ProcessJobItem(SyncJobItem jobItem, IProgress progress, CancellationToken cancellationToken) { var item = _libraryManager.GetItemById(jobItem.ItemId); if (item == null) @@ -372,12 +375,12 @@ namespace MediaBrowser.Server.Implementations.Sync var video = item as Video; if (video != null) { - await Sync(jobItem, video, deviceProfile, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, video, deviceProfile, progress, cancellationToken).ConfigureAwait(false); } else if (item is Audio) { - await Sync(jobItem, (Audio)item, deviceProfile, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, (Audio)item, deviceProfile, progress, cancellationToken).ConfigureAwait(false); } else if (item is Photo) @@ -391,7 +394,7 @@ namespace MediaBrowser.Server.Implementations.Sync } } - private async Task Sync(SyncJobItem jobItem, Video item, DeviceProfile profile, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Video item, DeviceProfile profile, IProgress progress, CancellationToken cancellationToken) { var options = new VideoOptions { @@ -412,7 +415,26 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Status = SyncJobItemStatus.Converting; await _syncRepo.Update(jobItem).ConfigureAwait(false); - jobItem.OutputPath = await _mediaEncoder.EncodeVideo(new EncodingJobOptions(streamInfo, profile), new Progress(), cancellationToken); + try + { + jobItem.OutputPath = await _mediaEncoder.EncodeVideo(new EncodingJobOptions(streamInfo, profile), progress, + cancellationToken); + } + catch (OperationCanceledException) + { + jobItem.Status = SyncJobItemStatus.Queued; + } + catch (Exception ex) + { + jobItem.Status = SyncJobItemStatus.Failed; + _logger.ErrorException("Error during sync transcoding", ex); + } + + if (jobItem.Status == SyncJobItemStatus.Failed || jobItem.Status == SyncJobItemStatus.Queued) + { + await _syncRepo.Update(jobItem).ConfigureAwait(false); + return; + } } else { @@ -435,7 +457,7 @@ namespace MediaBrowser.Server.Implementations.Sync await _syncRepo.Update(jobItem).ConfigureAwait(false); } - private async Task Sync(SyncJobItem jobItem, Audio item, DeviceProfile profile, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Audio item, DeviceProfile profile, IProgress progress, CancellationToken cancellationToken) { var options = new AudioOptions { @@ -455,8 +477,26 @@ namespace MediaBrowser.Server.Implementations.Sync { jobItem.Status = SyncJobItemStatus.Converting; await _syncRepo.Update(jobItem).ConfigureAwait(false); - - jobItem.OutputPath = await _mediaEncoder.EncodeAudio(new EncodingJobOptions(streamInfo, profile), new Progress(), cancellationToken); + + try + { + jobItem.OutputPath = await _mediaEncoder.EncodeAudio(new EncodingJobOptions(streamInfo, profile), progress, cancellationToken); + } + catch (OperationCanceledException) + { + jobItem.Status = SyncJobItemStatus.Queued; + } + catch (Exception ex) + { + jobItem.Status = SyncJobItemStatus.Failed; + _logger.ErrorException("Error during sync transcoding", ex); + } + + if (jobItem.Status == SyncJobItemStatus.Failed || jobItem.Status == SyncJobItemStatus.Queued) + { + await _syncRepo.Update(jobItem).ConfigureAwait(false); + return; + } } else { diff --git a/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs b/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs index c2925551b7..068261ffd3 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs @@ -67,7 +67,7 @@ namespace MediaBrowser.Server.Implementations.Sync public bool IsHidden { - get { return true; } + get { return false; } } public bool IsEnabled diff --git a/SharedVersion.cs b/SharedVersion.cs index d53462b93c..70c7bbf8c4 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -//[assembly: AssemblyVersion("3.0.*")] -[assembly: AssemblyVersion("3.0.5482.1")] +[assembly: AssemblyVersion("3.0.*")] +//[assembly: AssemblyVersion("3.0.5482.1")] From 01be627d8bf329655b580d220dc62fe9906519fa Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 5 Jan 2015 22:25:23 -0500 Subject: [PATCH 02/11] sync updates --- .../BaseApplicationHost.cs | 2 +- .../Devices/DeviceId.cs | 24 ++--------------- MediaBrowser.Model/Sync/SyncJobItem.cs | 5 ++++ .../MediaInfo/VideoImageProvider.cs | 21 +++++++++++++-- .../Localization/Server/server.json | 5 ++++ ...MediaBrowser.Server.Implementations.csproj | 2 +- .../Sync/SyncJobProcessor.cs | 27 ++++++++++++------- .../Sync/SyncManager.cs | 13 ++++++++- .../Sync/SyncRepository.cs | 27 ++++++++++--------- .../packages.config | 2 +- .../Api/PackageCreator.cs | 1 + .../MediaBrowser.WebDashboard.csproj | 6 +++++ 12 files changed, 86 insertions(+), 49 deletions(-) diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index 4de1adcfa8..3e25bb6269 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -186,7 +186,7 @@ namespace MediaBrowser.Common.Implementations { if (_deviceId == null) { - _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"), NetworkManager); + _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId")); } return _deviceId.Value; diff --git a/MediaBrowser.Common.Implementations/Devices/DeviceId.cs b/MediaBrowser.Common.Implementations/Devices/DeviceId.cs index 7c0dc1e1f0..2a1c8877d7 100644 --- a/MediaBrowser.Common.Implementations/Devices/DeviceId.cs +++ b/MediaBrowser.Common.Implementations/Devices/DeviceId.cs @@ -1,6 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; using MediaBrowser.Model.Logging; using System; using System.IO; @@ -11,7 +9,6 @@ namespace MediaBrowser.Common.Implementations.Devices public class DeviceId { private readonly IApplicationPaths _appPaths; - private readonly INetworkManager _networkManager; private readonly ILogger _logger; private readonly object _syncLock = new object(); @@ -73,23 +70,7 @@ namespace MediaBrowser.Common.Implementations.Devices private string GetNewId() { - // When generating an Id, base it off of the app path + mac address - // But we can't fail here, so if we can't get the mac address then just use a random guid - - string mac; - - try - { - mac = _networkManager.GetMacAddress(); - } - catch - { - mac = Guid.NewGuid().ToString("N"); - } - - mac += "-" + _appPaths.ApplicationPath; - - return mac.GetMD5().ToString("N"); + return Guid.NewGuid().ToString("N"); } private string GetDeviceId() @@ -107,11 +88,10 @@ namespace MediaBrowser.Common.Implementations.Devices private string _id; - public DeviceId(IApplicationPaths appPaths, ILogger logger, INetworkManager networkManager) + public DeviceId(IApplicationPaths appPaths, ILogger logger) { _appPaths = appPaths; _logger = logger; - _networkManager = networkManager; } public string Value diff --git a/MediaBrowser.Model/Sync/SyncJobItem.cs b/MediaBrowser.Model/Sync/SyncJobItem.cs index 4090d82b0b..3d06943aa3 100644 --- a/MediaBrowser.Model/Sync/SyncJobItem.cs +++ b/MediaBrowser.Model/Sync/SyncJobItem.cs @@ -73,5 +73,10 @@ namespace MediaBrowser.Model.Sync /// /// The primary image tag. public string PrimaryImageTag { get; set; } + /// + /// Gets or sets a value indicating whether [requires conversion]. + /// + /// true if [requires conversion]; otherwise, false. + public bool RequiresConversion { get; set; } } } diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index 7f55ce1ac2..59db382ead 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -1,5 +1,6 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Drawing; @@ -18,12 +19,14 @@ namespace MediaBrowser.Providers.MediaInfo private readonly IIsoManager _isoManager; private readonly IMediaEncoder _mediaEncoder; private readonly IServerConfigurationManager _config; + private readonly ILibraryManager _libraryManager; - public VideoImageProvider(IIsoManager isoManager, IMediaEncoder mediaEncoder, IServerConfigurationManager config) + public VideoImageProvider(IIsoManager isoManager, IMediaEncoder mediaEncoder, IServerConfigurationManager config, ILibraryManager libraryManager) { _isoManager = isoManager; _mediaEncoder = mediaEncoder; _config = config; + _libraryManager = libraryManager; } /// @@ -123,7 +126,21 @@ namespace MediaBrowser.Providers.MediaInfo { var video = item as Video; - return item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder && !video.IsShortcut && !video.IsArchive; + if (item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder && + !video.IsShortcut && !video.IsArchive) + { + if (video.GetType() == typeof(Video)) + { + if (string.IsNullOrEmpty(_libraryManager.GetContentType(video))) + { + return false; + } + } + + return true; + } + + return false; } public int Order diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 2d00f3c767..c070f30776 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -35,6 +35,11 @@ "LabelChapterImageExtractionForMoviesHelp": "Extracting chapter images will allow clients to display graphical scene selection menus. The process can be slow, cpu-intensive and may require several gigabytes of space. It runs as a nightly scheduled task at 4am, although this is configurable in the scheduled tasks area. It is not recommended to run this task during peak usage hours.", "LabelEnableAutomaticPortMapping": "Enable automatic port mapping", "LabelEnableAutomaticPortMappingHelp": "UPnP allows automated router configuration for easy remote access. This may not work with some router models.", + "HeaderTermsOfService": "Media Browser Terms of Service", + "MessagePleaseAcceptTermsOfService": "Please accept the terms of service and privacy policy before continuing.", + "OptionIAcceptTermsOfService": "I accept the terms of service", + "ButtonPrivacyPolicy": "Privacy policy", + "ButtonTermsOfService": "Terms of Service", "ButtonOk": "Ok", "ButtonCancel": "Cancel", "ButtonNew": "New", diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index ccc0737e96..81054b3c5a 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -51,7 +51,7 @@ False - ..\packages\MediaBrowser.Naming.1.0.0.24\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll + ..\packages\MediaBrowser.Naming.1.0.0.25\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll False diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index b09bfe91fb..698806d09d 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -340,16 +340,17 @@ namespace MediaBrowser.Server.Implementations.Sync var innerProgress = new ActionableProgress(); - await ProcessJobItem(item, innerProgress, cancellationToken).ConfigureAwait(false); - var job = _syncRepo.GetJob(item.JobId); + await ProcessJobItem(job, item, innerProgress, cancellationToken).ConfigureAwait(false); + + job = _syncRepo.GetJob(item.JobId); await UpdateJobStatus(job).ConfigureAwait(false); index++; } } - private async Task ProcessJobItem(SyncJobItem jobItem, IProgress progress, CancellationToken cancellationToken) + private async Task ProcessJobItem(SyncJob job, SyncJobItem jobItem, IProgress progress, CancellationToken cancellationToken) { var item = _libraryManager.GetItemById(jobItem.ItemId); if (item == null) @@ -372,15 +373,17 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Progress = 0; jobItem.Status = SyncJobItemStatus.Converting; + var user = _userManager.GetUserById(job.UserId); + var video = item as Video; if (video != null) { - await Sync(jobItem, video, deviceProfile, progress, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, video, user, deviceProfile, progress, cancellationToken).ConfigureAwait(false); } else if (item is Audio) { - await Sync(jobItem, (Audio)item, deviceProfile, progress, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, (Audio)item, user, deviceProfile, progress, cancellationToken).ConfigureAwait(false); } else if (item is Photo) @@ -394,7 +397,7 @@ namespace MediaBrowser.Server.Implementations.Sync } } - private async Task Sync(SyncJobItem jobItem, Video item, DeviceProfile profile, IProgress progress, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Video item, User user, DeviceProfile profile, IProgress progress, CancellationToken cancellationToken) { var options = new VideoOptions { @@ -402,7 +405,7 @@ namespace MediaBrowser.Server.Implementations.Sync ItemId = item.Id.ToString("N"), DeviceId = jobItem.TargetId, Profile = profile, - MediaSources = item.GetMediaSources(false).ToList() + MediaSources = item.GetMediaSources(false, user).ToList() }; var streamInfo = new StreamBuilder().BuildVideoItem(options); @@ -413,6 +416,7 @@ namespace MediaBrowser.Server.Implementations.Sync if (streamInfo.PlayMethod == PlayMethod.Transcode) { jobItem.Status = SyncJobItemStatus.Converting; + jobItem.RequiresConversion = true; await _syncRepo.Update(jobItem).ConfigureAwait(false); try @@ -438,6 +442,8 @@ namespace MediaBrowser.Server.Implementations.Sync } else { + jobItem.RequiresConversion = false; + if (mediaSource.Protocol == MediaProtocol.File) { jobItem.OutputPath = mediaSource.Path; @@ -457,7 +463,7 @@ namespace MediaBrowser.Server.Implementations.Sync await _syncRepo.Update(jobItem).ConfigureAwait(false); } - private async Task Sync(SyncJobItem jobItem, Audio item, DeviceProfile profile, IProgress progress, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Audio item, User user, DeviceProfile profile, IProgress progress, CancellationToken cancellationToken) { var options = new AudioOptions { @@ -465,7 +471,7 @@ namespace MediaBrowser.Server.Implementations.Sync ItemId = item.Id.ToString("N"), DeviceId = jobItem.TargetId, Profile = profile, - MediaSources = item.GetMediaSources(false).ToList() + MediaSources = item.GetMediaSources(false, user).ToList() }; var streamInfo = new StreamBuilder().BuildAudioItem(options); @@ -476,6 +482,7 @@ namespace MediaBrowser.Server.Implementations.Sync if (streamInfo.PlayMethod == PlayMethod.Transcode) { jobItem.Status = SyncJobItemStatus.Converting; + jobItem.RequiresConversion = true; await _syncRepo.Update(jobItem).ConfigureAwait(false); try @@ -500,6 +507,8 @@ namespace MediaBrowser.Server.Implementations.Sync } else { + jobItem.RequiresConversion = false; + if (mediaSource.Protocol == MediaProtocol.File) { jobItem.OutputPath = mediaSource.Path; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 3b2d70f849..b8f199e6bc 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -12,7 +12,6 @@ using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Sync; using MediaBrowser.Controller.TV; using MediaBrowser.Model.Dlna; -using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; @@ -393,6 +392,18 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Status = SyncJobItemStatus.Synced; jobItem.Progress = 100; + if (jobItem.RequiresConversion) + { + try + { + File.Delete(jobItem.OutputPath); + } + catch (Exception ex) + { + _logger.ErrorException("Error deleting temporary job file: {0}", ex, jobItem.OutputPath); + } + } + await _repo.Update(jobItem).ConfigureAwait(false); var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager, _tvSeriesManager, _mediaEncoder()); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 09c1b316ef..151860d84c 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -36,7 +36,7 @@ namespace MediaBrowser.Server.Implementations.Sync public async Task Initialize() { - var dbFile = Path.Combine(_appPaths.DataPath, "sync10.db"); + var dbFile = Path.Combine(_appPaths.DataPath, "sync11.db"); _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); @@ -45,7 +45,7 @@ namespace MediaBrowser.Server.Implementations.Sync "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Quality TEXT NOT NULL, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, Category TEXT, ParentId TEXT, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)", "create index if not exists idx_SyncJobs on SyncJobs(Id)", - "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT)", + "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, RequiresConversion BIT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT)", "create index if not exists idx_SyncJobItems on SyncJobs(Id)", //pragmas @@ -90,13 +90,14 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemCount"); _saveJobItemCommand = _connection.CreateCommand(); - _saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, OutputPath, Status, TargetId, DateCreated, Progress) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @OutputPath, @Status, @TargetId, @DateCreated, @Progress)"; + _saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, RequiresConversion, OutputPath, Status, TargetId, DateCreated, Progress) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @RequiresConversion, @OutputPath, @Status, @TargetId, @DateCreated, @Progress)"; _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Id"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@ItemId"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@ItemName"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@MediaSourceId"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@JobId"); + _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@RequiresConversion"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@OutputPath"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Status"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@TargetId"); @@ -105,7 +106,7 @@ namespace MediaBrowser.Server.Implementations.Sync } private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs"; - private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, OutputPath, Status, TargetId, DateCreated, Progress from SyncJobItems"; + private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, RequiresConversion, OutputPath, Status, TargetId, DateCreated, Progress from SyncJobItems"; public SyncJob GetJob(string id) { @@ -556,6 +557,7 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobItemCommand.GetParameter(index++).Value = jobItem.ItemName; _saveJobItemCommand.GetParameter(index++).Value = jobItem.MediaSourceId; _saveJobItemCommand.GetParameter(index++).Value = jobItem.JobId; + _saveJobItemCommand.GetParameter(index++).Value = jobItem.RequiresConversion; _saveJobItemCommand.GetParameter(index++).Value = jobItem.OutputPath; _saveJobItemCommand.GetParameter(index++).Value = jobItem.Status.ToString(); _saveJobItemCommand.GetParameter(index++).Value = jobItem.TargetId; @@ -618,24 +620,25 @@ namespace MediaBrowser.Server.Implementations.Sync } info.JobId = reader.GetString(4); + info.RequiresConversion = reader.GetBoolean(5); - if (!reader.IsDBNull(5)) + if (!reader.IsDBNull(6)) { - info.OutputPath = reader.GetString(5); + info.OutputPath = reader.GetString(6); } - if (!reader.IsDBNull(6)) + if (!reader.IsDBNull(7)) { - info.Status = (SyncJobItemStatus)Enum.Parse(typeof(SyncJobItemStatus), reader.GetString(6), true); + info.Status = (SyncJobItemStatus)Enum.Parse(typeof(SyncJobItemStatus), reader.GetString(7), true); } - info.TargetId = reader.GetString(7); + info.TargetId = reader.GetString(8); - info.DateCreated = reader.GetDateTime(8); + info.DateCreated = reader.GetDateTime(9); - if (!reader.IsDBNull(9)) + if (!reader.IsDBNull(10)) { - info.Progress = reader.GetDouble(9); + info.Progress = reader.GetDouble(10); } return info; diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 239bca4059..aba7d0e330 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 2f9f3f5f57..a6707bac3a 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -471,6 +471,7 @@ namespace MediaBrowser.WebDashboard.Api "userprofilespage.js", "userparentalcontrol.js", "userlibraryaccess.js", + "wizardagreement.js", "wizardfinishpage.js", "wizardservice.js", "wizardstartpage.js", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 1343b1e69f..7979f35aea 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -120,6 +120,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -1638,6 +1641,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest From f96b4083a05dec099e1c024719f0e8d6e98c9b27 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 8 Jan 2015 22:26:40 -0500 Subject: [PATCH 03/11] fix mp4 seeking in firefox --- MediaBrowser.sln | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/MediaBrowser.sln b/MediaBrowser.sln index c081917fb7..b25eb58ba7 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.30723.0 +VisualStudioVersion = 12.0.31101.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F0E0E64C-2A6F-4E35-9533-D53AC07C2CD1}" EndProject @@ -518,7 +518,4 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(Performance) = preSolution - HasPerformanceSessions = true - EndGlobalSection EndGlobal From baf5e0c18b9c3daf168bd4f39b167e059ce47736 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 8 Jan 2015 22:27:44 -0500 Subject: [PATCH 04/11] remove generic video excludes --- MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs | 9 --------- MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs | 8 -------- MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs | 9 --------- 3 files changed, 26 deletions(-) diff --git a/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs index cad08e6383..eb1a0b78c6 100644 --- a/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/MovieXmlSaver.cs @@ -54,15 +54,6 @@ namespace MediaBrowser.LocalMetadata.Savers // Check parent for null to avoid running this against things like video backdrops if (video != null && !(item is Episode) && !video.IsOwnedItem) { - // If it's a plain video, skip if content type is unset (unless editing) - if (video.GetType() == typeof(Video)) - { - if (updateType < ItemUpdateType.MetadataEdit && string.IsNullOrEmpty(_libraryManager.GetContentType(video))) - { - return false; - } - } - return updateType >= ItemUpdateType.MetadataDownload; } diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index 59db382ead..7c32432251 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -129,14 +129,6 @@ namespace MediaBrowser.Providers.MediaInfo if (item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder && !video.IsShortcut && !video.IsArchive) { - if (video.GetType() == typeof(Video)) - { - if (string.IsNullOrEmpty(_libraryManager.GetContentType(video))) - { - return false; - } - } - return true; } diff --git a/MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs index d049843f35..e67aa42c75 100644 --- a/MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs @@ -7,7 +7,6 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Xml; @@ -55,14 +54,6 @@ namespace MediaBrowser.XbmcMetadata.Savers // Check parent for null to avoid running this against things like video backdrops if (video != null && !(item is Episode) && !video.IsOwnedItem) { - // If it's a plain video, skip if content type is unset (unless editing) - if (video.GetType() == typeof (Video)) - { - if (updateType < ItemUpdateType.MetadataEdit && string.IsNullOrEmpty(LibraryManager.GetContentType(video))) - { - return false; - } - } return updateType >= MinimumUpdateType; } From aff870aaafc29b08127f7ea62e96ba8a3a60c0f8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 8 Jan 2015 22:34:09 -0500 Subject: [PATCH 05/11] search ignore accent chars --- .../Library/CoreResolutionIgnoreRule.cs | 10 ++++++++-- .../Library/SearchEngine.cs | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs b/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs index 1628ccc328..1771bbdb2c 100644 --- a/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs +++ b/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.IO; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; @@ -114,7 +115,12 @@ namespace MediaBrowser.Server.Implementations.Library } // Ignore samples - if (filename.IndexOf(".sample.", StringComparison.OrdinalIgnoreCase) != -1) + var sampleFilename = " " + filename.Replace(".", " ", StringComparison.OrdinalIgnoreCase) + .Replace("-", " ", StringComparison.OrdinalIgnoreCase) + .Replace("_", " ", StringComparison.OrdinalIgnoreCase) + .Replace("!", " ", StringComparison.OrdinalIgnoreCase); + + if (sampleFilename.IndexOf(" sample ", StringComparison.OrdinalIgnoreCase) != -1) { return true; } diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index 071031b25b..1c92f6c4af 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Entities; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; @@ -97,6 +98,8 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentNullException("searchTerm"); } + searchTerm = searchTerm.RemoveDiacritics(); + var terms = GetWords(searchTerm); var hints = new List>(); @@ -318,6 +321,8 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentNullException("input"); } + input = input.RemoveDiacritics(); + if (string.Equals(input, searchInput, StringComparison.OrdinalIgnoreCase)) { return new Tuple(searchInput, 0); From 7e59c0700c8d3a3cfe5467dcea33cd9545878ae5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 8 Jan 2015 23:05:45 -0500 Subject: [PATCH 06/11] fix multidisc albums --- .../Library/Resolvers/Audio/MusicAlbumResolver.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index 0f703cb22b..a1c762283b 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -1,7 +1,5 @@ using MediaBrowser.Common.IO; using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; @@ -159,7 +157,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio return false; } - return discSubfolderCount > 0 && discSubfolderCount > 10; + return discSubfolderCount > 0; } private static bool IsMultiDiscFolder(string path) From 3e13f409d229660445784c7525f550b81fcfdab1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 8 Jan 2015 23:08:36 -0500 Subject: [PATCH 07/11] fix movie resolver with unset content type --- .../Library/Resolvers/Movies/MovieResolver.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 441fada6ab..334a994744 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -68,12 +68,12 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies return ResolveVideos False - ..\packages\MediaBrowser.Naming.1.0.0.25\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll + ..\packages\MediaBrowser.Naming.1.0.0.27\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll False diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index aba7d0e330..e838757dc6 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/SharedVersion.cs b/SharedVersion.cs index 70c7bbf8c4..65f786cebb 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; [assembly: AssemblyVersion("3.0.*")] -//[assembly: AssemblyVersion("3.0.5482.1")] +//[assembly: AssemblyVersion("3.0.5482.3")] From 51b5e379d56eaa77ab0e93edcb87477f524bf804 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 10 Jan 2015 00:53:35 -0500 Subject: [PATCH 10/11] add options for media in archives --- MediaBrowser.Api/PackageService.cs | 4 +- MediaBrowser.Api/PluginService.cs | 27 +++++++++- MediaBrowser.LocalMetadata/BaseXmlProvider.cs | 8 +++ .../Configuration/ServerConfiguration.cs | 3 ++ MediaBrowser.Model/Plugins/PluginInfo.cs | 8 ++- .../FileOrganization/EpisodeFileOrganizer.cs | 4 +- .../Library/LibraryManager.cs | 35 ++++++++++--- .../Resolvers/Audio/MusicAlbumResolver.cs | 16 +++--- .../Resolvers/Audio/MusicArtistResolver.cs | 6 ++- .../Library/Resolvers/BaseVideoResolver.cs | 8 ++- .../Library/Resolvers/Movies/MovieResolver.cs | 49 +++++++++++++++++-- .../Library/Resolvers/TV/SeasonResolver.cs | 9 +++- .../Library/Resolvers/TV/SeriesResolver.cs | 4 +- .../Localization/JavaScript/javascript.json | 5 +- .../Localization/Server/server.json | 7 ++- 15 files changed, 155 insertions(+), 38 deletions(-) diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs index 136969b170..1d792fbc16 100644 --- a/MediaBrowser.Api/PackageService.cs +++ b/MediaBrowser.Api/PackageService.cs @@ -186,9 +186,9 @@ namespace MediaBrowser.Api /// /// The request. /// System.Object. - public object Get(GetPackages request) + public async Task Get(GetPackages request) { - var packages = _installationManager.GetAvailablePackages(CancellationToken.None, request.PackageType, _appHost.ApplicationVersion).Result; + var packages = await _installationManager.GetAvailablePackages(CancellationToken.None, request.PackageType, _appHost.ApplicationVersion).ConfigureAwait(false); if (!string.IsNullOrEmpty(request.TargetSystems)) { diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index b4e12184aa..62aa1e755a 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common; +using System.Threading; +using MediaBrowser.Common; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Security; using MediaBrowser.Common.Updates; @@ -13,6 +14,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; namespace MediaBrowser.Api { @@ -155,10 +157,31 @@ namespace MediaBrowser.Api /// /// The request. /// System.Object. - public object Get(GetPlugins request) + public async Task Get(GetPlugins request) { var result = _appHost.Plugins.OrderBy(p => p.Name).Select(p => p.GetPluginInfo()).ToList(); + // Don't fail just on account of image url's + try + { + var packages = (await _installationManager.GetAvailablePackagesWithoutRegistrationInfo(CancellationToken.None)) + .ToList(); + + foreach (var plugin in result) + { + var pkg = packages.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i.guid) && new Guid(plugin.Id).Equals(new Guid(i.guid))); + + if (pkg != null) + { + plugin.ImageUrl = pkg.thumbImage; + } + } + } + catch + { + + } + return ToOptimizedSerializedResultUsingCache(result); } diff --git a/MediaBrowser.LocalMetadata/BaseXmlProvider.cs b/MediaBrowser.LocalMetadata/BaseXmlProvider.cs index 74e3b61caa..7c60df4cbd 100644 --- a/MediaBrowser.LocalMetadata/BaseXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/BaseXmlProvider.cs @@ -76,6 +76,14 @@ namespace MediaBrowser.LocalMetadata } } + public int Order + { + get + { + // After Nfo + return 1; + } + } } static class XmlProviderUtils diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 6c941e8048..241ff61956 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -175,6 +175,9 @@ namespace MediaBrowser.Model.Configuration public NameValuePair[] ContentTypes { get; set; } + public bool EnableAudioArchiveFiles { get; set; } + public bool EnableVideoArchiveFiles { get; set; } + /// /// Initializes a new instance of the class. /// diff --git a/MediaBrowser.Model/Plugins/PluginInfo.cs b/MediaBrowser.Model/Plugins/PluginInfo.cs index e84c06c218..06fa2322b3 100644 --- a/MediaBrowser.Model/Plugins/PluginInfo.cs +++ b/MediaBrowser.Model/Plugins/PluginInfo.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Model.Updates; -using System; +using System; namespace MediaBrowser.Model.Plugins { @@ -49,5 +48,10 @@ namespace MediaBrowser.Model.Plugins /// /// The unique id. public string Id { get; set; } + /// + /// Gets or sets the image URL. + /// + /// The image URL. + public string ImageUrl { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index a4ac22eea1..611f887eed 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -16,6 +16,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Server.Implementations.Library; namespace MediaBrowser.Server.Implementations.FileOrganization { @@ -55,7 +56,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization FileSize = new FileInfo(path).Length }; - var resolver = new Naming.TV.EpisodeResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger()); + var namingOptions = ((LibraryManager) _libraryManager).GetNamingOptions(); + var resolver = new Naming.TV.EpisodeResolver(namingOptions, new Naming.Logging.NullLogger()); var episodeInfo = resolver.Resolve(path, FileInfoType.File) ?? new Naming.TV.EpisodeInfo(); diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 48bddd6a81..ab72d89fd8 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1754,24 +1754,24 @@ namespace MediaBrowser.Server.Implementations.Library public bool IsVideoFile(string path) { - var resolver = new VideoResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger()); + var resolver = new VideoResolver(GetNamingOptions(), new Naming.Logging.NullLogger()); return resolver.IsVideoFile(path); } public bool IsAudioFile(string path) { - var parser = new AudioFileParser(new ExtendedNamingOptions()); + var parser = new AudioFileParser(GetNamingOptions()); return parser.IsAudioFile(path); } public int? GetSeasonNumberFromPath(string path) { - return new SeasonPathParser(new ExtendedNamingOptions(), new RegexProvider()).Parse(path, true, true).SeasonNumber; + return new SeasonPathParser(GetNamingOptions(), new RegexProvider()).Parse(path, true, true).SeasonNumber; } public bool FillMissingEpisodeNumbersFromPath(Episode episode) { - var resolver = new EpisodeResolver(new ExtendedNamingOptions(), + var resolver = new EpisodeResolver(GetNamingOptions(), new Naming.Logging.NullLogger()); var fileType = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd || episode.VideoType == VideoType.HdDvd ? @@ -1889,9 +1889,28 @@ namespace MediaBrowser.Server.Implementations.Library return changed; } + public NamingOptions GetNamingOptions() + { + var options = new ExtendedNamingOptions(); + + if (!ConfigurationManager.Configuration.EnableAudioArchiveFiles) + { + options.AudioFileExtensions.Remove(".rar"); + options.AudioFileExtensions.Remove(".zip"); + } + + if (!ConfigurationManager.Configuration.EnableVideoArchiveFiles) + { + options.VideoFileExtensions.Remove(".rar"); + options.VideoFileExtensions.Remove(".zip"); + } + + return options; + } + public ItemLookupInfo ParseName(string name) { - var resolver = new VideoResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger()); + var resolver = new VideoResolver(GetNamingOptions(), new Naming.Logging.NullLogger()); var result = resolver.CleanDateTime(name); var cleanName = resolver.CleanString(result.Name); @@ -1910,7 +1929,7 @@ namespace MediaBrowser.Server.Implementations.Library .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly)) .ToList(); - var videoListResolver = new VideoListResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger()); + var videoListResolver = new VideoListResolver(GetNamingOptions(), new Naming.Logging.NullLogger()); var videos = videoListResolver.Resolve(fileSystemChildren.Select(i => new PortableFileInfo { @@ -1963,7 +1982,7 @@ namespace MediaBrowser.Server.Implementations.Library .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly)) .ToList(); - var videoListResolver = new VideoListResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger()); + var videoListResolver = new VideoListResolver(GetNamingOptions(), new Naming.Logging.NullLogger()); var videos = videoListResolver.Resolve(fileSystemChildren.Select(i => new PortableFileInfo { @@ -2001,7 +2020,7 @@ namespace MediaBrowser.Server.Implementations.Library private void SetExtraTypeFromFilename(Video item) { - var resolver = new ExtraResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger(), new RegexProvider()); + var resolver = new ExtraResolver(GetNamingOptions(), new Naming.Logging.NullLogger(), new RegexProvider()); var result = resolver.GetExtraInfo(item.Path); diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index d1a6cbbf84..7c8ddabebf 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -74,14 +74,10 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio /// /// The path. /// The directory service. - /// The logger. - /// The file system. - /// The library manager. /// true if [is music album] [the specified data]; otherwise, false. - public static bool IsMusicAlbum(string path, IDirectoryService directoryService, ILogger logger, IFileSystem fileSystem, - ILibraryManager libraryManager) + public bool IsMusicAlbum(string path, IDirectoryService directoryService) { - return ContainsMusic(directoryService.GetFileSystemEntries(path), true, directoryService, logger, fileSystem, libraryManager); + return ContainsMusic(directoryService.GetFileSystemEntries(path), true, directoryService, _logger, _fileSystem, _libraryManager); } /// @@ -111,7 +107,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio /// The file system. /// The library manager. /// true if the specified list contains music; otherwise, false. - private static bool ContainsMusic(IEnumerable list, + private bool ContainsMusic(IEnumerable list, bool allowSubfolders, IDirectoryService directoryService, ILogger logger, @@ -169,9 +165,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio return discSubfolderCount > 0; } - private static bool IsMultiDiscFolder(string path) + private bool IsMultiDiscFolder(string path) { - var parser = new AlbumParser(new ExtendedNamingOptions(), new Naming.Logging.NullLogger()); + var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(); + + var parser = new AlbumParser(namingOptions, new Naming.Logging.NullLogger()); var result = parser.ParseMultiPart(path); return result.IsMultiPart; diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs index edbc87415f..9f3f248653 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs @@ -70,9 +70,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio } var directoryService = args.DirectoryService; - + + 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 => MusicAlbumResolver.IsMusicAlbum(i.FullName, directoryService, _logger, _fileSystem, _libraryManager)) ? new MusicArtist() : null; + return args.FileSystemChildren.Where(i => (i.Attributes & FileAttributes.Directory) == FileAttributes.Directory).Any(i => albumResolver.IsMusicAlbum(i.FullName, directoryService)) ? new MusicArtist() : null; } } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs index 8e2218b0ad..1a4d35af55 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs @@ -44,8 +44,10 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers protected TVideoType ResolveVideo(ItemResolveArgs args, bool parseName) where TVideoType : Video, new() { + var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions(); + // If the path is a file check for a matching extensions - var parser = new Naming.Video.VideoResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger()); + var parser = new Naming.Video.VideoResolver(namingOptions, new Naming.Logging.NullLogger()); if (args.IsDirectory) { @@ -229,7 +231,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers protected void Set3DFormat(Video video) { - var resolver = new Format3DParser(new ExtendedNamingOptions(), new Naming.Logging.NullLogger()); + var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions(); + + var resolver = new Format3DParser(namingOptions, new Naming.Logging.NullLogger()); var result = resolver.Parse(video.Path); Set3DFormat(video, result.Is3D, result.Format3D); diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 334a994744..4c0767b08a 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -1,10 +1,11 @@ -using MediaBrowser.Controller.Entities; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; -using MediaBrowser.Naming.Common; using MediaBrowser.Naming.IO; using MediaBrowser.Naming.Video; using System; @@ -68,6 +69,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies return ResolveVideos private readonly IServerConfigurationManager _config; + private readonly ILibraryManager _libraryManager; + /// /// Initializes a new instance of the class. /// /// The config. - public SeasonResolver(IServerConfigurationManager config) + public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager) { _config = config; + _libraryManager = libraryManager; } /// @@ -34,9 +37,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV { if (args.Parent is Series && args.IsDirectory) { + var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(); + var season = new Season { - IndexNumber = new SeasonPathParser(new ExtendedNamingOptions(), new RegexProvider()).Parse(args.Path, true, true).SeasonNumber + IndexNumber = new SeasonPathParser(namingOptions, new RegexProvider()).Parse(args.Path, true, true).SeasonNumber }; if (season.IndexNumber.HasValue && season.IndexNumber.Value == 0) diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index ee0fe6b948..261eb96c4b 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -141,7 +141,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV return true; } - var episodeResolver = new Naming.TV.EpisodeResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger()); + var namingOptions = ((LibraryManager)libraryManager).GetNamingOptions(); + + var episodeResolver = new Naming.TV.EpisodeResolver(namingOptions, new Naming.Logging.NullLogger()); var episodeInfo = episodeResolver.Resolve(fullName, FileInfoType.File, false); if (episodeInfo != null && episodeInfo.EpisodeNumber.HasValue) { diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index aff6308463..efbfd5e2c6 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -262,10 +262,13 @@ "MessagePleaseEnterNameOrId": "Please enter a name or an external Id.", "MessageValueNotCorrect": "The value entered is not correct. Please try again.", "MessageItemSaved": "Item saved.", + "MessagePleaseAcceptTermsOfServiceBeforeContinuing": "Please accept the terms of service before continuing.", "OptionEnded": "Ended", "OptionContinuing": "Continuing", "OptionOff": "Off", "OptionOn": "On", + "ButtonSettings": "Settings", + "ButtonUninstall": "Uninstall", "HeaderFields": "Fields", "HeaderFieldsHelp": "Slide a field to 'off' to lock it and prevent it's data from being changed.", "HeaderLiveTV": "Live TV", @@ -674,5 +677,5 @@ "SyncJobItemStatusFailed": "Failed", "SyncJobItemStatusRemovedFromDevice": "Removed from device", "SyncJobItemStatusCancelled": "Cancelled", - "MessageJobItemHasNoActions": "d" + "MessageJobItemHasNoActions": "d" } diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index c5097959eb..78bb5fa359 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -43,8 +43,13 @@ "ButtonOk": "Ok", "ButtonCancel": "Cancel", "ButtonNew": "New", + "HeaderTV": "TV", + "HeaderAudio": "Audio", + "HeaderVideo": "Video", + "OptionDetectArchiveFilesAsMedia": "Detect archive files as media", + "OptionDetectArchiveFilesAsMediaHelp": "If enabled, files with .rar and .zip extensions will be detected as media files.", "LabelEnterConnectUserName": "User name or email:", - "LabelEnterConnectUserNameHelp": "This is your Media Browser online account user name or password.", + "LabelEnterConnectUserNameHelp": "This is your Media Browser online account user name or password.", "HeaderSyncJobInfo": "Sync Job", "FolderTypeMixed": "Mixed content", "FolderTypeMovies": "Movies", From e97848289600570b489b6fdb608014b383772523 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 10 Jan 2015 01:55:37 -0500 Subject: [PATCH 11/11] 3.0.5482.4 --- .../Library/Resolvers/TV/SeriesResolver.cs | 10 +++++----- .../Sync/SyncScheduledTask.cs | 2 +- SharedVersion.cs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index 261eb96c4b..e68f005bef 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -72,13 +72,13 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV } else { - if (args.HasParent()) - { - return null; - } - if (string.IsNullOrWhiteSpace(collectionType)) { + if (args.HasParent()) + { + return null; + } + if (args.Parent.IsRoot) { return null; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs b/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs index 068261ffd3..c2925551b7 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs @@ -67,7 +67,7 @@ namespace MediaBrowser.Server.Implementations.Sync public bool IsHidden { - get { return false; } + get { return true; } } public bool IsEnabled diff --git a/SharedVersion.cs b/SharedVersion.cs index 65f786cebb..d681f2ca92 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -[assembly: AssemblyVersion("3.0.*")] -//[assembly: AssemblyVersion("3.0.5482.3")] +//[assembly: AssemblyVersion("3.0.*")] +[assembly: AssemblyVersion("3.0.5482.4")]