using System.IO;
namespace EmbyToolbox.Services;
///
/// Сценарии для запоминания последних каталогов в диалогах открытия/сохранения.
///
public enum RecentPathScenario
{
SeriesRenamer,
ConversionAddFiles,
ConversionAddFolder,
Merge,
VideoInfoOpenFile,
SettingsTempFolder,
SettingsOutputFolder,
TrackExtractDestination
}
///
/// Запоминает последние каталоги по сценариям и общий каталог; сохраняет вместе с .
///
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;
}
///
/// Дополнительный существующий каталог перед стандартным «Видео» (для TEMP: текущий выбранный каталог из настроек).
///
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 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 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;
}
}
}