emby-toolbox/EmbyToolbox/Services/RecentPathService.cs
Emby Toolbox 6264b487fe Initial commit: Emby Toolbox (conversion scroll fix, bulk Del for tracks).
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 21:33:47 +05:00

249 lines
7.9 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}