aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MediaBrowser.Api/Library/FileOrganizationService.cs47
-rw-r--r--MediaBrowser.Api/MediaBrowser.Api.csproj1
-rw-r--r--MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs4
-rw-r--r--MediaBrowser.Controller/Persistence/IFileOrganizationRepository.cs4
-rw-r--r--MediaBrowser.Providers/TV/SeriesPostScanTask.cs17
-rw-r--r--MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs4
-rw-r--r--MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs7
-rw-r--r--MediaBrowser.Server.Implementations/FileOrganization/TvFileSorter.cs34
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs6
9 files changed, 102 insertions, 22 deletions
diff --git a/MediaBrowser.Api/Library/FileOrganizationService.cs b/MediaBrowser.Api/Library/FileOrganizationService.cs
new file mode 100644
index 000000000..529a75506
--- /dev/null
+++ b/MediaBrowser.Api/Library/FileOrganizationService.cs
@@ -0,0 +1,47 @@
+using MediaBrowser.Controller.FileOrganization;
+using MediaBrowser.Model.FileOrganization;
+using MediaBrowser.Model.Querying;
+using ServiceStack;
+
+namespace MediaBrowser.Api.Library
+{
+ [Route("/Library/FileOrganization/Results", "GET")]
+ [Api(Description = "Gets file organization results")]
+ public class GetFileOrganizationActivity : IReturn<QueryResult<FileOrganizationResult>>
+ {
+ /// <summary>
+ /// Skips over a given number of items within the results. Use for paging.
+ /// </summary>
+ /// <value>The start index.</value>
+ [ApiMember(Name = "StartIndex", Description = "Optional. The record index to start at. All items with a lower index will be dropped from the results.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+ public int? StartIndex { get; set; }
+
+ /// <summary>
+ /// The maximum number of items to return
+ /// </summary>
+ /// <value>The limit.</value>
+ [ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+ public int? Limit { get; set; }
+ }
+
+ public class FileOrganizationService : BaseApiService
+ {
+ private readonly IFileOrganizationService _iFileOrganizationService;
+
+ public FileOrganizationService(IFileOrganizationService iFileOrganizationService)
+ {
+ _iFileOrganizationService = iFileOrganizationService;
+ }
+
+ public object Get(GetFileOrganizationActivity request)
+ {
+ var result = _iFileOrganizationService.GetResults(new FileOrganizationResultQuery
+ {
+ Limit = request.Limit,
+ StartIndex = request.Limit
+ });
+
+ return ToOptimizedResult(result);
+ }
+ }
+}
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index a46f82ae0..f9dfadd1f 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -87,6 +87,7 @@
<Compile Include="ItemRefreshService.cs" />
<Compile Include="ItemUpdateService.cs" />
<Compile Include="LibraryService.cs" />
+ <Compile Include="Library\FileOrganizationService.cs" />
<Compile Include="Library\LibraryHelpers.cs" />
<Compile Include="Library\LibraryService.cs" />
<Compile Include="Library\LibraryStructureService.cs" />
diff --git a/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs b/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs
index 993c04c28..58a612508 100644
--- a/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs
+++ b/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs
@@ -1,5 +1,5 @@
using MediaBrowser.Model.FileOrganization;
-using System.Collections.Generic;
+using MediaBrowser.Model.Querying;
using System.Threading;
using System.Threading.Tasks;
@@ -25,6 +25,6 @@ namespace MediaBrowser.Controller.FileOrganization
/// </summary>
/// <param name="query">The query.</param>
/// <returns>IEnumerable{FileOrganizationResult}.</returns>
- IEnumerable<FileOrganizationResult> GetResults(FileOrganizationResultQuery query);
+ QueryResult<FileOrganizationResult> GetResults(FileOrganizationResultQuery query);
}
}
diff --git a/MediaBrowser.Controller/Persistence/IFileOrganizationRepository.cs b/MediaBrowser.Controller/Persistence/IFileOrganizationRepository.cs
index 9f5cc1579..47cfcb56e 100644
--- a/MediaBrowser.Controller/Persistence/IFileOrganizationRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IFileOrganizationRepository.cs
@@ -1,5 +1,5 @@
using MediaBrowser.Model.FileOrganization;
-using System.Collections.Generic;
+using MediaBrowser.Model.Querying;
using System.Threading;
using System.Threading.Tasks;
@@ -20,6 +20,6 @@ namespace MediaBrowser.Controller.Persistence
/// </summary>
/// <param name="query">The query.</param>
/// <returns>IEnumerable{FileOrganizationResult}.</returns>
- IEnumerable<FileOrganizationResult> GetResults(FileOrganizationResultQuery query);
+ QueryResult<FileOrganizationResult> GetResults(FileOrganizationResultQuery query);
}
}
diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
index cc24cad5d..adc61fb73 100644
--- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
+++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
@@ -59,7 +59,7 @@ namespace MediaBrowser.Providers.TV
await new MissingEpisodeProvider(_logger, _config).Run(seriesGroups, cancellationToken).ConfigureAwait(false);
var numComplete = 0;
-
+
foreach (var series in seriesList)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -68,9 +68,7 @@ namespace MediaBrowser.Providers.TV
.OfType<Episode>()
.ToList();
- series.SpecialFeatureIds = episodes
- .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
- .Select(i => i.Id)
+ var physicalEpisodes = episodes.Where(i => i.LocationType != LocationType.Virtual)
.ToList();
series.SeasonCount = episodes
@@ -79,7 +77,12 @@ namespace MediaBrowser.Providers.TV
.Distinct()
.Count();
- series.DateLastEpisodeAdded = episodes.Select(i => i.DateCreated)
+ series.SpecialFeatureIds = physicalEpisodes
+ .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
+ .Select(i => i.Id)
+ .ToList();
+
+ series.DateLastEpisodeAdded = physicalEpisodes.Select(i => i.DateCreated)
.OrderByDescending(i => i)
.FirstOrDefault();
@@ -166,7 +169,7 @@ namespace MediaBrowser.Providers.TV
if (_config.Configuration.EnableInternetProviders)
{
- hasNewEpisodes = await AddMissingEpisodes(group, seriesDataPath, episodeLookup, cancellationToken)
+ hasNewEpisodes = await AddMissingEpisodes(group.ToList(), seriesDataPath, episodeLookup, cancellationToken)
.ConfigureAwait(false);
}
@@ -225,7 +228,7 @@ namespace MediaBrowser.Providers.TV
/// <param name="episodeLookup">The episode lookup.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- private async Task<bool> AddMissingEpisodes(IEnumerable<Series> series, string seriesDataPath, IEnumerable<Tuple<int, int>> episodeLookup, CancellationToken cancellationToken)
+ private async Task<bool> AddMissingEpisodes(List<Series> series, string seriesDataPath, IEnumerable<Tuple<int, int>> episodeLookup, CancellationToken cancellationToken)
{
var existingEpisodes = series.SelectMany(s => s.RecursiveChildren.OfType<Episode>()).ToList();
diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs
index 9d8236bde..bcbff7488 100644
--- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs
+++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs
@@ -2,7 +2,7 @@
using MediaBrowser.Controller.FileOrganization;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.FileOrganization;
-using System.Collections.Generic;
+using MediaBrowser.Model.Querying;
using System.Threading;
using System.Threading.Tasks;
@@ -30,7 +30,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
return _repo.SaveResult(result, cancellationToken);
}
- public IEnumerable<FileOrganizationResult> GetResults(FileOrganizationResultQuery query)
+ public QueryResult<FileOrganizationResult> GetResults(FileOrganizationResultQuery query)
{
return _repo.GetResults(query);
}
diff --git a/MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs b/MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs
index 5c5a83cb6..35a3ba087 100644
--- a/MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs
+++ b/MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs
@@ -2,6 +2,7 @@
using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.FileOrganization;
+using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Logging;
using System;
@@ -18,14 +19,16 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
private readonly ILibraryManager _libraryManager;
private readonly IFileSystem _fileSystem;
private readonly IFileOrganizationService _iFileSortingRepository;
+ private readonly IDirectoryWatchers _directoryWatchers;
- public OrganizerScheduledTask(IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager, IFileSystem fileSystem, IFileOrganizationService iFileSortingRepository)
+ public OrganizerScheduledTask(IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager, IFileSystem fileSystem, IFileOrganizationService iFileSortingRepository, IDirectoryWatchers directoryWatchers)
{
_config = config;
_logger = logger;
_libraryManager = libraryManager;
_fileSystem = fileSystem;
_iFileSortingRepository = iFileSortingRepository;
+ _directoryWatchers = directoryWatchers;
}
public string Name
@@ -45,7 +48,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
{
- return new TvFileSorter(_libraryManager, _logger, _fileSystem, _iFileSortingRepository).Sort(_config.Configuration.TvFileOrganizationOptions, cancellationToken, progress);
+ return new TvFileSorter(_libraryManager, _logger, _fileSystem, _iFileSortingRepository, _directoryWatchers).Sort(_config.Configuration.TvFileOrganizationOptions, cancellationToken, progress);
}
public IEnumerable<ITaskTrigger> GetDefaultTriggers()
diff --git a/MediaBrowser.Server.Implementations/FileOrganization/TvFileSorter.cs b/MediaBrowser.Server.Implementations/FileOrganization/TvFileSorter.cs
index 24e2c094b..72f0da207 100644
--- a/MediaBrowser.Server.Implementations/FileOrganization/TvFileSorter.cs
+++ b/MediaBrowser.Server.Implementations/FileOrganization/TvFileSorter.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.FileOrganization;
+using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
@@ -24,15 +25,17 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly IFileOrganizationService _iFileSortingRepository;
+ private readonly IDirectoryWatchers _directoryWatchers;
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
- public TvFileSorter(ILibraryManager libraryManager, ILogger logger, IFileSystem fileSystem, IFileOrganizationService iFileSortingRepository)
+ public TvFileSorter(ILibraryManager libraryManager, ILogger logger, IFileSystem fileSystem, IFileOrganizationService iFileSortingRepository, IDirectoryWatchers directoryWatchers)
{
_libraryManager = libraryManager;
_logger = logger;
_fileSystem = fileSystem;
_iFileSortingRepository = iFileSortingRepository;
+ _directoryWatchers = directoryWatchers;
}
public async Task Sort(TvFileOrganizationOptions options, CancellationToken cancellationToken, IProgress<double> progress)
@@ -48,6 +51,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
progress.Report(10);
+ var scanLibrary = false;
+
if (eligibleFiles.Count > 0)
{
var allSeries = _libraryManager.RootFolder
@@ -59,7 +64,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
foreach (var file in eligibleFiles)
{
- await SortFile(file.FullName, options, allSeries).ConfigureAwait(false);
+ var result = await SortFile(file.FullName, options, allSeries).ConfigureAwait(false);
+
+ if (result.Status == FileSortingStatus.Success)
+ {
+ scanLibrary = true;
+ }
numComplete++;
double percent = numComplete;
@@ -88,6 +98,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
}
}
+ if (scanLibrary)
+ {
+ await _libraryManager.ValidateMediaLibrary(new Progress<double>(), CancellationToken.None)
+ .ConfigureAwait(false);
+ }
+
progress.Report(100);
}
@@ -118,7 +134,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
/// <param name="path">The path.</param>
/// <param name="options">The options.</param>
/// <param name="allSeries">All series.</param>
- private Task SortFile(string path, TvFileOrganizationOptions options, IEnumerable<Series> allSeries)
+ private async Task<FileOrganizationResult> SortFile(string path, TvFileOrganizationOptions options, IEnumerable<Series> allSeries)
{
_logger.Info("Sorting file {0}", path);
@@ -169,7 +185,9 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
_logger.Warn(msg);
}
- return LogResult(result);
+ await LogResult(result).ConfigureAwait(false);
+
+ return result;
}
/// <summary>
@@ -236,6 +254,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
/// <param name="copy">if set to <c>true</c> [copy].</param>
private void PerformFileSorting(TvFileOrganizationOptions options, FileOrganizationResult result, bool copy)
{
+ _directoryWatchers.TemporarilyIgnore(result.TargetPath);
+
try
{
if (copy)
@@ -250,11 +270,17 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
catch (Exception ex)
{
var errorMsg = string.Format("Failed to move file from {0} to {1}", result.OriginalPath, result.TargetPath);
+
result.Status = FileSortingStatus.Failure;
result.ErrorMessage = errorMsg;
_logger.ErrorException(errorMsg, ex);
+
return;
}
+ finally
+ {
+ _directoryWatchers.RemoveTempIgnore(result.TargetPath);
+ }
if (copy)
{
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs
index a95f84f06..e397cc280 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs
@@ -2,8 +2,8 @@
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.FileOrganization;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Querying;
using System;
-using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Threading;
@@ -62,9 +62,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
return Task.FromResult(true);
}
- public IEnumerable<FileOrganizationResult> GetResults(FileOrganizationResultQuery query)
+ public QueryResult<FileOrganizationResult> GetResults(FileOrganizationResultQuery query)
{
- return new List<FileOrganizationResult>();
+ return new QueryResult<FileOrganizationResult>();
}
/// <summary>