Merge pull request #1432 from softworkz/SeriesDetectionV2
Supersedes #1192: Auto-Organize - Added feature to remember/persist series matching in manual organization dialog
This commit is contained in:
commit
b398b4eaab
|
@ -74,6 +74,34 @@ namespace MediaBrowser.Api.Library
|
|||
public bool RememberCorrection { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Library/FileOrganizationSmartMatch", "GET", Summary = "Gets smart match entries")]
|
||||
public class GetSmartMatchInfos : IReturn<QueryResult<SmartMatchInfo>>
|
||||
{
|
||||
/// <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; }
|
||||
}
|
||||
|
||||
[Route("/Library/FileOrganizationSmartMatch/{Id}/Delete", "POST", Summary = "Deletes a smart match entry")]
|
||||
public class DeleteSmartMatchEntry
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "Item ID", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[ApiMember(Name = "MatchString", Description = "SmartMatch String", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||
public string MatchString { get; set; }
|
||||
}
|
||||
|
||||
[Authenticated(Roles = "Admin")]
|
||||
public class FileOrganizationService : BaseApiService
|
||||
{
|
||||
|
@ -130,5 +158,21 @@ namespace MediaBrowser.Api.Library
|
|||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
public object Get(GetSmartMatchInfos request)
|
||||
{
|
||||
var result = _iFileOrganizationService.GetSmartMatchInfos(new FileOrganizationResultQuery
|
||||
{
|
||||
Limit = request.Limit,
|
||||
StartIndex = request.StartIndex
|
||||
});
|
||||
|
||||
return ToOptimizedSerializedResultUsingCache(result);
|
||||
}
|
||||
|
||||
public void Post(DeleteSmartMatchEntry request)
|
||||
{
|
||||
_iFileOrganizationService.DeleteSmartMatchEntry(request.Id, request.MatchString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,5 +67,19 @@ namespace MediaBrowser.Controller.FileOrganization
|
|||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveResult(FileOrganizationResult result, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of smart match entries
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>IEnumerable{SmartMatchInfo}.</returns>
|
||||
QueryResult<SmartMatchInfo> GetSmartMatchInfos(FileOrganizationResultQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a smart match entry.
|
||||
/// </summary>
|
||||
/// <param name="Id">Item Id.</param>
|
||||
/// <param name="matchString">The match string to delete.</param>
|
||||
void DeleteSmartMatchEntry(string Id, string matchString);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -668,6 +668,9 @@
|
|||
<Compile Include="..\MediaBrowser.Model\FileOrganization\FileSortingStatus.cs">
|
||||
<Link>FileOrganization\FileSortingStatus.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\FileOrganization\SmartMatchInfo.cs">
|
||||
<Link>FileOrganization\SmartMatchInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\FileOrganization\TvFileOrganizationOptions.cs">
|
||||
<Link>FileOrganization\TvFileOrganizationOptions.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -633,6 +633,9 @@
|
|||
<Compile Include="..\MediaBrowser.Model\FileOrganization\FileSortingStatus.cs">
|
||||
<Link>FileOrganization\FileSortingStatus.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\FileOrganization\SmartMatchInfo.cs">
|
||||
<Link>FileOrganization\SmartMatchInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\FileOrganization\TvFileOrganizationOptions.cs">
|
||||
<Link>FileOrganization\TvFileOrganizationOptions.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
namespace MediaBrowser.Model.FileOrganization
|
||||
{
|
||||
public class AutoOrganizeOptions
|
||||
|
@ -9,9 +10,16 @@ namespace MediaBrowser.Model.FileOrganization
|
|||
/// <value>The tv options.</value>
|
||||
public TvFileOrganizationOptions TvOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a list of smart match entries.
|
||||
/// </summary>
|
||||
/// <value>The smart match entries.</value>
|
||||
public List<SmartMatchInfo> SmartMatchInfos { get; set; }
|
||||
|
||||
public AutoOrganizeOptions()
|
||||
{
|
||||
TvOptions = new TvFileOrganizationOptions();
|
||||
SmartMatchInfos = new List<SmartMatchInfo>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
19
MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs
Normal file
19
MediaBrowser.Model/FileOrganization/SmartMatchInfo.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Model.FileOrganization
|
||||
{
|
||||
public class SmartMatchInfo
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public FileOrganizerType OrganizerType { get; set; }
|
||||
public List<string> MatchStrings { get; set; }
|
||||
|
||||
public SmartMatchInfo()
|
||||
{
|
||||
MatchStrings = new List<string>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -137,6 +137,7 @@
|
|||
<Compile Include="Dto\MetadataEditorInfo.cs" />
|
||||
<Compile Include="Dto\NameIdPair.cs" />
|
||||
<Compile Include="Dto\NameValuePair.cs" />
|
||||
<Compile Include="FileOrganization\SmartMatchInfo.cs" />
|
||||
<Compile Include="MediaInfo\LiveStreamRequest.cs" />
|
||||
<Compile Include="MediaInfo\LiveStreamResponse.cs" />
|
||||
<Compile Include="MediaInfo\PlaybackInfoRequest.cs" />
|
||||
|
|
|
@ -46,12 +46,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
|
||||
public Task<FileOrganizationResult> OrganizeEpisodeFile(string path, CancellationToken cancellationToken)
|
||||
{
|
||||
var options = _config.GetAutoOrganizeOptions().TvOptions;
|
||||
var options = _config.GetAutoOrganizeOptions();
|
||||
|
||||
return OrganizeEpisodeFile(path, options, false, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<FileOrganizationResult> OrganizeEpisodeFile(string path, TvFileOrganizationOptions options, bool overwriteExisting, CancellationToken cancellationToken)
|
||||
public async Task<FileOrganizationResult> OrganizeEpisodeFile(string path, AutoOrganizeOptions options, bool overwriteExisting, CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.Info("Sorting file {0}", path);
|
||||
|
||||
|
@ -110,6 +110,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
premiereDate,
|
||||
options,
|
||||
overwriteExisting,
|
||||
false,
|
||||
result,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -145,7 +146,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task<FileOrganizationResult> OrganizeWithCorrection(EpisodeFileOrganizationRequest request, TvFileOrganizationOptions options, CancellationToken cancellationToken)
|
||||
public async Task<FileOrganizationResult> OrganizeWithCorrection(EpisodeFileOrganizationRequest request, AutoOrganizeOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = _organizationService.GetResult(request.ResultId);
|
||||
|
||||
|
@ -159,6 +160,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
null,
|
||||
options,
|
||||
true,
|
||||
request.RememberCorrection,
|
||||
result,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
@ -173,12 +175,13 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
int? episodeNumber,
|
||||
int? endingEpiosdeNumber,
|
||||
DateTime? premiereDate,
|
||||
TvFileOrganizationOptions options,
|
||||
AutoOrganizeOptions options,
|
||||
bool overwriteExisting,
|
||||
bool rememberCorrection,
|
||||
FileOrganizationResult result,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var series = GetMatchingSeries(seriesName, result);
|
||||
var series = GetMatchingSeries(seriesName, result, options);
|
||||
|
||||
if (series == null)
|
||||
{
|
||||
|
@ -197,6 +200,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
premiereDate,
|
||||
options,
|
||||
overwriteExisting,
|
||||
rememberCorrection,
|
||||
result,
|
||||
cancellationToken);
|
||||
}
|
||||
|
@ -207,15 +211,18 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
int? episodeNumber,
|
||||
int? endingEpiosdeNumber,
|
||||
DateTime? premiereDate,
|
||||
TvFileOrganizationOptions options,
|
||||
AutoOrganizeOptions options,
|
||||
bool overwriteExisting,
|
||||
bool rememberCorrection,
|
||||
FileOrganizationResult result,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.Info("Sorting file {0} into series {1}", sourcePath, series.Path);
|
||||
|
||||
var originalExtractedSeriesString = result.ExtractedName;
|
||||
|
||||
// Proceed to sort the file
|
||||
var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options, cancellationToken).ConfigureAwait(false);
|
||||
var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options.TvOptions, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (string.IsNullOrEmpty(newPath))
|
||||
{
|
||||
|
@ -234,7 +241,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
|
||||
if (!overwriteExisting)
|
||||
{
|
||||
if (options.CopyOriginalFile && fileExists && IsSameEpisode(sourcePath, newPath))
|
||||
if (options.TvOptions.CopyOriginalFile && fileExists && IsSameEpisode(sourcePath, newPath))
|
||||
{
|
||||
_logger.Info("File {0} already copied to new path {1}, stopping organization", sourcePath, newPath);
|
||||
result.Status = FileSortingStatus.SkippedExisting;
|
||||
|
@ -251,7 +258,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
}
|
||||
}
|
||||
|
||||
PerformFileSorting(options, result);
|
||||
PerformFileSorting(options.TvOptions, result);
|
||||
|
||||
if (overwriteExisting)
|
||||
{
|
||||
|
@ -285,6 +292,31 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rememberCorrection)
|
||||
{
|
||||
SaveSmartMatchString(originalExtractedSeriesString, series, options);
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveSmartMatchString(string matchString, Series series, AutoOrganizeOptions options)
|
||||
{
|
||||
SmartMatchInfo info = options.SmartMatchInfos.Find(i => i.Id == series.Id);
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
info = new SmartMatchInfo();
|
||||
info.Id = series.Id;
|
||||
info.OrganizerType = FileOrganizerType.Episode;
|
||||
info.Name = series.Name;
|
||||
options.SmartMatchInfos.Add(info);
|
||||
}
|
||||
|
||||
if (!info.MatchStrings.Contains(matchString, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
info.MatchStrings.Add(matchString);
|
||||
_config.SaveAutoOrganizeOptions(options);
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteLibraryFile(string path, bool renameRelatedFiles, string targetPath)
|
||||
|
@ -435,7 +467,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
}
|
||||
}
|
||||
|
||||
private Series GetMatchingSeries(string seriesName, FileOrganizationResult result)
|
||||
private Series GetMatchingSeries(string seriesName, FileOrganizationResult result, AutoOrganizeOptions options)
|
||||
{
|
||||
var parsedName = _libraryManager.ParseName(seriesName);
|
||||
|
||||
|
@ -445,13 +477,28 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
result.ExtractedName = nameWithoutYear;
|
||||
result.ExtractedYear = yearInName;
|
||||
|
||||
return _libraryManager.RootFolder.GetRecursiveChildren(i => i is Series)
|
||||
var series = _libraryManager.RootFolder.GetRecursiveChildren(i => i is Series)
|
||||
.Cast<Series>()
|
||||
.Select(i => NameUtils.GetMatchScore(nameWithoutYear, yearInName, i))
|
||||
.Where(i => i.Item2 > 0)
|
||||
.OrderByDescending(i => i.Item2)
|
||||
.Select(i => i.Item1)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (series == null)
|
||||
{
|
||||
SmartMatchInfo info = options.SmartMatchInfos.Where(e => e.MatchStrings.Contains(seriesName, StringComparer.OrdinalIgnoreCase)).FirstOrDefault();
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
series = _libraryManager.RootFolder.GetRecursiveChildren(i => i is Series)
|
||||
.Cast<Series>()
|
||||
.Where(i => i.Id == info.Id)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
return series ?? new Series();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -10,6 +10,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
{
|
||||
return manager.GetConfiguration<AutoOrganizeOptions>("autoorganize");
|
||||
}
|
||||
public static void SaveAutoOrganizeOptions(this IConfigurationManager manager, AutoOrganizeOptions options)
|
||||
{
|
||||
manager.SaveConfiguration("autoorganize", options);
|
||||
}
|
||||
}
|
||||
|
||||
public class AutoOrganizeOptionsFactory : IConfigurationFactory
|
||||
|
|
|
@ -11,6 +11,7 @@ using MediaBrowser.Model.Logging;
|
|||
using MediaBrowser.Model.Querying;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CommonIO;
|
||||
|
@ -96,9 +97,9 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
return _repo.Delete(resultId);
|
||||
}
|
||||
|
||||
private TvFileOrganizationOptions GetTvOptions()
|
||||
private AutoOrganizeOptions GetAutoOrganizeptions()
|
||||
{
|
||||
return _config.GetAutoOrganizeOptions().TvOptions;
|
||||
return _config.GetAutoOrganizeOptions();
|
||||
}
|
||||
|
||||
public async Task PerformOrganization(string resultId)
|
||||
|
@ -113,7 +114,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager,
|
||||
_libraryMonitor, _providerManager);
|
||||
|
||||
await organizer.OrganizeEpisodeFile(result.OriginalPath, GetTvOptions(), true, CancellationToken.None)
|
||||
await organizer.OrganizeEpisodeFile(result.OriginalPath, GetAutoOrganizeptions(), true, CancellationToken.None)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@ -127,7 +128,55 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
var organizer = new EpisodeFileOrganizer(this, _config, _fileSystem, _logger, _libraryManager,
|
||||
_libraryMonitor, _providerManager);
|
||||
|
||||
await organizer.OrganizeWithCorrection(request, GetTvOptions(), CancellationToken.None).ConfigureAwait(false);
|
||||
await organizer.OrganizeWithCorrection(request, GetAutoOrganizeptions(), CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public QueryResult<SmartMatchInfo> GetSmartMatchInfos(FileOrganizationResultQuery query)
|
||||
{
|
||||
if (query == null)
|
||||
{
|
||||
throw new ArgumentNullException("query");
|
||||
}
|
||||
|
||||
var options = GetAutoOrganizeptions();
|
||||
|
||||
var items = options.SmartMatchInfos.Skip(query.StartIndex ?? 0).Take(query.Limit ?? Int32.MaxValue);
|
||||
|
||||
return new QueryResult<SmartMatchInfo>()
|
||||
{
|
||||
Items = items.ToArray(),
|
||||
TotalRecordCount = items.Count()
|
||||
};
|
||||
}
|
||||
|
||||
public void DeleteSmartMatchEntry(string IdString, string matchString)
|
||||
{
|
||||
Guid Id;
|
||||
|
||||
if (!Guid.TryParse(IdString, out Id))
|
||||
{
|
||||
throw new ArgumentNullException("Id");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(matchString))
|
||||
{
|
||||
throw new ArgumentNullException("matchString");
|
||||
}
|
||||
|
||||
var options = GetAutoOrganizeptions();
|
||||
|
||||
SmartMatchInfo info = options.SmartMatchInfos.Find(i => i.Id == Id);
|
||||
|
||||
if (info != null && info.MatchStrings.Contains(matchString))
|
||||
{
|
||||
info.MatchStrings.Remove(matchString);
|
||||
if (info.MatchStrings.Count == 0)
|
||||
{
|
||||
options.SmartMatchInfos.Remove(info);
|
||||
}
|
||||
|
||||
_config.SaveAutoOrganizeOptions(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,17 +50,17 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
get { return "Library"; }
|
||||
}
|
||||
|
||||
private TvFileOrganizationOptions GetTvOptions()
|
||||
private AutoOrganizeOptions GetAutoOrganizeOptions()
|
||||
{
|
||||
return _config.GetAutoOrganizeOptions().TvOptions;
|
||||
return _config.GetAutoOrganizeOptions();
|
||||
}
|
||||
|
||||
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
||||
{
|
||||
if (GetTvOptions().IsEnabled)
|
||||
if (GetAutoOrganizeOptions().TvOptions.IsEnabled)
|
||||
{
|
||||
await new TvFolderOrganizer(_libraryManager, _logger, _fileSystem, _libraryMonitor, _organizationService, _config, _providerManager)
|
||||
.Organize(GetTvOptions(), cancellationToken, progress).ConfigureAwait(false);
|
||||
.Organize(GetAutoOrganizeOptions(), cancellationToken, progress).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,12 +74,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
|
||||
public bool IsHidden
|
||||
{
|
||||
get { return !GetTvOptions().IsEnabled; }
|
||||
get { return !GetAutoOrganizeOptions().TvOptions.IsEnabled; }
|
||||
}
|
||||
|
||||
public bool IsEnabled
|
||||
{
|
||||
get { return GetTvOptions().IsEnabled; }
|
||||
get { return GetAutoOrganizeOptions().TvOptions.IsEnabled; }
|
||||
}
|
||||
|
||||
public bool IsActivityLogged
|
||||
|
|
|
@ -52,13 +52,13 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
return false;
|
||||
}
|
||||
|
||||
public async Task Organize(TvFileOrganizationOptions options, CancellationToken cancellationToken, IProgress<double> progress)
|
||||
public async Task Organize(AutoOrganizeOptions options, CancellationToken cancellationToken, IProgress<double> progress)
|
||||
{
|
||||
var watchLocations = options.WatchLocations.ToList();
|
||||
var watchLocations = options.TvOptions.WatchLocations.ToList();
|
||||
|
||||
var eligibleFiles = watchLocations.SelectMany(GetFilesToOrganize)
|
||||
.OrderBy(_fileSystem.GetCreationTimeUtc)
|
||||
.Where(i => EnableOrganization(i, options))
|
||||
.Where(i => EnableOrganization(i, options.TvOptions))
|
||||
.ToList();
|
||||
|
||||
var processedFolders = new HashSet<string>();
|
||||
|
@ -76,7 +76,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
|
||||
try
|
||||
{
|
||||
var result = await organizer.OrganizeEpisodeFile(file.FullName, options, options.OverwriteExistingEpisodes, cancellationToken).ConfigureAwait(false);
|
||||
var result = await organizer.OrganizeEpisodeFile(file.FullName, options, options.TvOptions.OverwriteExistingEpisodes, cancellationToken).ConfigureAwait(false);
|
||||
if (result.Status == FileSortingStatus.Success && !processedFolders.Contains(file.DirectoryName, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
processedFolders.Add(file.DirectoryName);
|
||||
|
@ -100,7 +100,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
|
||||
foreach (var path in processedFolders)
|
||||
{
|
||||
var deleteExtensions = options.LeftOverFileExtensionsToDelete
|
||||
var deleteExtensions = options.TvOptions.LeftOverFileExtensionsToDelete
|
||||
.Select(i => i.Trim().TrimStart('.'))
|
||||
.Where(i => !string.IsNullOrEmpty(i))
|
||||
.Select(i => "." + i)
|
||||
|
@ -111,7 +111,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
|||
DeleteLeftOverFiles(path, deleteExtensions);
|
||||
}
|
||||
|
||||
if (options.DeleteEmptyFolders)
|
||||
if (options.TvOptions.DeleteEmptyFolders)
|
||||
{
|
||||
if (!IsWatchFolder(path, watchLocations))
|
||||
{
|
||||
|
|
|
@ -101,6 +101,12 @@
|
|||
<Content Include="dashboard-ui\components\chromecasthelpers.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\autoorganizesmart.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\bower_components\fastclick\lib\fastclick.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\components\recordingcreator\recordingcreator.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@ -281,6 +287,9 @@
|
|||
<Content Include="dashboard-ui\scripts\mysyncsettings.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\scripts\autoorganizesmart.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\scripts\searchmenu.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
|
Loading…
Reference in New Issue
Block a user