249 lines
7.9 KiB
C#
249 lines
7.9 KiB
C#
using System.IO;
|
||
|
||
namespace EmbyToolbox.Services;
|
||
|
||
/// <summary>
|
||
/// Сценарии для запоминания последних каталогов в диалогах открытия/сохранения.
|
||
/// </summary>
|
||
public enum RecentPathScenario
|
||
{
|
||
SeriesRenamer,
|
||
ConversionAddFiles,
|
||
ConversionAddFolder,
|
||
Merge,
|
||
VideoInfoOpenFile,
|
||
SettingsTempFolder,
|
||
SettingsOutputFolder,
|
||
TrackExtractDestination
|
||
}
|
||
|
||
/// <summary>
|
||
/// Запоминает последние каталоги по сценариям и общий каталог; сохраняет вместе с <see cref="AppSettings"/>.
|
||
/// </summary>
|
||
public sealed class RecentPathService
|
||
{
|
||
private readonly AppSettingsService _settingsService;
|
||
|
||
private string? _lastSeriesRenamerFolder;
|
||
private string? _lastConversionFilesFolder;
|
||
private string? _lastConversionFolder;
|
||
private string? _lastMergeFolder;
|
||
private string? _lastVideoInfoFolder;
|
||
private string? _lastTempFolder;
|
||
private string? _lastOutputFolder;
|
||
private string? _lastTrackExtractDestinationFolder;
|
||
private string? _lastCommonFolder;
|
||
|
||
public RecentPathService(AppSettingsService settingsService)
|
||
{
|
||
_settingsService = settingsService;
|
||
}
|
||
|
||
public void HydrateFrom(AppSettings settings)
|
||
{
|
||
_lastSeriesRenamerFolder = settings.LastSeriesRenamerFolder;
|
||
_lastConversionFilesFolder = settings.LastConversionFilesFolder;
|
||
_lastConversionFolder = settings.LastConversionFolder;
|
||
_lastMergeFolder = settings.LastMergeFolder;
|
||
_lastVideoInfoFolder = settings.LastVideoInfoFolder;
|
||
_lastTempFolder = settings.LastTempFolder;
|
||
_lastOutputFolder = settings.LastOutputFolder;
|
||
_lastTrackExtractDestinationFolder = settings.LastTrackExtractDestinationFolder;
|
||
_lastCommonFolder = settings.LastCommonFolder;
|
||
}
|
||
|
||
public void ApplyTo(AppSettings target)
|
||
{
|
||
target.LastSeriesRenamerFolder = _lastSeriesRenamerFolder;
|
||
target.LastConversionFilesFolder = _lastConversionFilesFolder;
|
||
target.LastConversionFolder = _lastConversionFolder;
|
||
target.LastMergeFolder = _lastMergeFolder;
|
||
target.LastVideoInfoFolder = _lastVideoInfoFolder;
|
||
target.LastTempFolder = _lastTempFolder;
|
||
target.LastOutputFolder = _lastOutputFolder;
|
||
target.LastTrackExtractDestinationFolder = _lastTrackExtractDestinationFolder;
|
||
target.LastCommonFolder = _lastCommonFolder;
|
||
}
|
||
|
||
/// <param name="extraFolderFallbackBeforeDefault">
|
||
/// Дополнительный существующий каталог перед стандартным «Видео» (для TEMP: текущий выбранный каталог из настроек).
|
||
/// </param>
|
||
public string GetInitialDirectory(RecentPathScenario scenario, string? extraFolderFallbackBeforeDefault = null)
|
||
{
|
||
foreach (var candidate in GetCandidateChain(scenario, extraFolderFallbackBeforeDefault))
|
||
{
|
||
if (IsUsableExistingDirectory(candidate))
|
||
{
|
||
return candidate!;
|
||
}
|
||
}
|
||
|
||
return Environment.GetFolderPath(Environment.SpecialFolder.MyVideos);
|
||
}
|
||
|
||
public void RememberChosenFiles(RecentPathScenario scenario, IReadOnlyList<string> chosenFilePaths)
|
||
{
|
||
if (chosenFilePaths.Count == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
var dir = NormalizeExistingDirectory(Path.GetDirectoryName(chosenFilePaths[0]));
|
||
if (dir is null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
SetScenarioFolder(scenario, dir);
|
||
_lastCommonFolder = dir;
|
||
Persist();
|
||
}
|
||
|
||
public string? GetNormalizedRememberedFolderPath(RecentPathScenario scenario)
|
||
{
|
||
var folder = GetScenarioStored(scenario);
|
||
if (string.IsNullOrWhiteSpace(folder))
|
||
{
|
||
return null;
|
||
}
|
||
|
||
try
|
||
{
|
||
return Path.GetFullPath(folder.Trim());
|
||
}
|
||
catch
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
|
||
public void RememberChosenFolder(RecentPathScenario scenario, string folderPathOrFile)
|
||
{
|
||
var dir = NormalizeExistingDirectory(folderPathOrFile);
|
||
if (dir is null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
SetScenarioFolder(scenario, dir);
|
||
_lastCommonFolder = dir;
|
||
Persist();
|
||
}
|
||
|
||
private IEnumerable<string?> GetCandidateChain(RecentPathScenario scenario, string? extraFolderFallbackBeforeDefault)
|
||
{
|
||
yield return GetScenarioStored(scenario);
|
||
yield return _lastCommonFolder;
|
||
if (!string.IsNullOrWhiteSpace(extraFolderFallbackBeforeDefault))
|
||
{
|
||
yield return NormalizePathOnly(extraFolderFallbackBeforeDefault);
|
||
}
|
||
}
|
||
|
||
private string? GetScenarioStored(RecentPathScenario scenario) =>
|
||
scenario switch
|
||
{
|
||
RecentPathScenario.SeriesRenamer => _lastSeriesRenamerFolder,
|
||
RecentPathScenario.ConversionAddFiles => _lastConversionFilesFolder,
|
||
RecentPathScenario.ConversionAddFolder => _lastConversionFolder,
|
||
RecentPathScenario.Merge => _lastMergeFolder,
|
||
RecentPathScenario.VideoInfoOpenFile => _lastVideoInfoFolder,
|
||
RecentPathScenario.SettingsTempFolder => _lastTempFolder,
|
||
RecentPathScenario.SettingsOutputFolder => _lastOutputFolder,
|
||
RecentPathScenario.TrackExtractDestination => _lastTrackExtractDestinationFolder,
|
||
_ => null
|
||
};
|
||
|
||
private void SetScenarioFolder(RecentPathScenario scenario, string normalizedDirectory)
|
||
{
|
||
switch (scenario)
|
||
{
|
||
case RecentPathScenario.SeriesRenamer:
|
||
_lastSeriesRenamerFolder = normalizedDirectory;
|
||
break;
|
||
case RecentPathScenario.ConversionAddFiles:
|
||
_lastConversionFilesFolder = normalizedDirectory;
|
||
break;
|
||
case RecentPathScenario.ConversionAddFolder:
|
||
_lastConversionFolder = normalizedDirectory;
|
||
break;
|
||
case RecentPathScenario.Merge:
|
||
_lastMergeFolder = normalizedDirectory;
|
||
break;
|
||
case RecentPathScenario.VideoInfoOpenFile:
|
||
_lastVideoInfoFolder = normalizedDirectory;
|
||
break;
|
||
case RecentPathScenario.SettingsTempFolder:
|
||
_lastTempFolder = normalizedDirectory;
|
||
break;
|
||
case RecentPathScenario.SettingsOutputFolder:
|
||
_lastOutputFolder = normalizedDirectory;
|
||
break;
|
||
case RecentPathScenario.TrackExtractDestination:
|
||
_lastTrackExtractDestinationFolder = normalizedDirectory;
|
||
break;
|
||
default:
|
||
throw new ArgumentOutOfRangeException(nameof(scenario), scenario, null);
|
||
}
|
||
}
|
||
|
||
private void Persist()
|
||
{
|
||
var disk = _settingsService.Load();
|
||
ApplyTo(disk);
|
||
_settingsService.Save(disk);
|
||
}
|
||
|
||
private static string? NormalizeExistingDirectory(string? path)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(path))
|
||
{
|
||
return null;
|
||
}
|
||
|
||
try
|
||
{
|
||
var full = Path.GetFullPath(path.Trim());
|
||
return Directory.Exists(full) ? full : null;
|
||
}
|
||
catch
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
|
||
private static string? NormalizePathOnly(string? path)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(path))
|
||
{
|
||
return null;
|
||
}
|
||
|
||
try
|
||
{
|
||
return Path.GetFullPath(path.Trim());
|
||
}
|
||
catch
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
|
||
private static bool IsUsableExistingDirectory(string? path)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(path))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
try
|
||
{
|
||
return Directory.Exists(Path.GetFullPath(path.Trim()));
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
}
|