Skip to content

Commit 18c3664

Browse files
author
Meyn
committed
Fix CommonDirectory calculation
1 parent 7161355 commit 18c3664

File tree

2 files changed

+79
-55
lines changed

2 files changed

+79
-55
lines changed

SpotifyToM3U/MVVM/Model/IOManager.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ private void LoadAudioFilesData()
158158
using TextReader dirReader = new StreamReader(SettingsSaveFilePath);
159159
string[] list = (serializer.Deserialize(dirReader) as string[]) ?? Array.Empty<string>();
160160
Array.ForEach(list, (x) => _libraryVM.RootPathes.Add(x));
161-
_exportVM.LibraryVM_AudioFilesModifified(this, null!);
162161

163162
_logger.Info($"Loaded {list.Length} root paths from settings");
164163
}

SpotifyToM3U/MVVM/ViewModel/ExportVM.cs

Lines changed: 79 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ internal partial class ExportVM : ViewModelObject
1919
#region Fields
2020

2121
private static readonly Logger _logger = SpotifyToM3ULogger.GetLogger(typeof(ExportVM));
22-
private SpotifyVM _spotifyVM;
23-
private LibraryVM _libraryVM;
22+
private readonly SpotifyVM _spotifyVM;
23+
private readonly LibraryVM _libraryVM;
2424

2525
#endregion
2626

@@ -47,7 +47,6 @@ public ExportVM(INavigationService navigation) : base(navigation)
4747
_spotifyVM = App.Current.ServiceProvider.GetRequiredService<SpotifyVM>();
4848
_libraryVM = App.Current.ServiceProvider.GetRequiredService<LibraryVM>();
4949
Navigation.PropertyChanged += Navigation_PropertyChanged;
50-
_libraryVM.AudioFilesModifified += LibraryVM_AudioFilesModifified;
5150
PropertyChanged += OnTextBoxPropertyChanged;
5251

5352
_logger.Info($"ExportVM initialized successfully. Default export path: {ExportPath}");
@@ -64,57 +63,94 @@ private void Navigation_PropertyChanged(object? sender, PropertyChangedEventArgs
6463
if (e.PropertyName == nameof(Navigation.CurrentView))
6564
{
6665
ExportIsVisible = false;
66+
CalculateExportRoot();
6767
}
6868
}
6969

70-
public void LibraryVM_AudioFilesModifified(object? sender, EventArgs e)
70+
private void CalculateExportRoot()
7171
{
72-
_logger.Debug("Library audio files modified, recalculating export root path");
73-
74-
try
72+
Task.Run(() =>
7573
{
76-
if (_libraryVM.RootPathes.Count == 0)
74+
try
7775
{
78-
_logger.Debug("No root paths available for relative export calculation");
79-
return;
80-
}
76+
List<string?> actualTrackPaths = _spotifyVM.PlaylistTracks
77+
.Where(track => track.IsLocal && !string.IsNullOrEmpty(track.Path))
78+
.Select(track => Path.GetDirectoryName(track.Path))
79+
.Where(dir => !string.IsNullOrEmpty(dir))
80+
.Distinct()
81+
.ToList();
82+
83+
if (actualTrackPaths.Count == 0)
84+
{
85+
_logger.Debug("No matched tracks found for relative export calculation");
86+
return;
87+
}
8188

82-
Task.Run(() =>
83-
{
84-
try
89+
_logger.Debug($"Calculating common root from {actualTrackPaths.Count} actual track directories");
90+
91+
string commonRoot = FindCommonRoot(actualTrackPaths);
92+
if (!string.IsNullOrEmpty(commonRoot) && commonRoot.Length > 3)
8593
{
86-
string[][] collection = _libraryVM.RootPathes.ToList().Select(x => x.Split("\\")).ToArray();
87-
List<string> rootPath = new();
88-
89-
for (int j = 0; j < collection[0].Length; j++)
90-
if (collection.All(x => x[j] == collection[0][j]))
91-
rootPath.Add(collection[0][j]);
92-
string path = string.Join("\\", rootPath);
93-
if (IOManager.TryGetFullPath(path, out path))
94-
{
95-
_exportRoot = path + "\\";
96-
CanAsRelativ = true;
97-
_logger.Info($"Export root path calculated: {_exportRoot}");
98-
}
99-
else
100-
{
101-
CanAsRelativ = false;
102-
_logger.Warn($"Invalid export root path calculated: {path}");
103-
}
94+
_exportRoot = !commonRoot.EndsWith("\\") ? commonRoot + "\\" : commonRoot;
95+
CanAsRelativ = true;
96+
_logger.Info($"Export root calculated from actual tracks: {_exportRoot}");
10497
}
105-
catch (Exception ex)
98+
else
10699
{
107-
_logger.Error(ex, "Error calculating export root path");
108-
CanAsRelativ = false;
100+
_logger.Debug($"Common root too generic or empty: '{commonRoot}'");
109101
}
110-
});
102+
}
103+
catch (Exception ex)
104+
{
105+
_logger.Error(ex, "Error calculating export root path");
106+
}
107+
});
108+
}
109+
110+
private static string FindCommonRoot(List<string?> paths)
111+
{
112+
if (paths.Count == 0) return string.Empty;
113+
if (paths.Count == 1) return paths[0] ?? string.Empty;
114+
115+
try
116+
{
117+
List<string[]> pathSegments = paths.ConvertAll(path => Path.GetFullPath(path!).Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries));
118+
119+
int minSegments = pathSegments.Min(segments => segments.Length);
120+
List<string> commonSegments = [];
121+
122+
for (int i = 0; i < minSegments; i++)
123+
{
124+
string currentSegment = pathSegments[0][i];
125+
if (pathSegments.All(segments => segments[i].Equals(currentSegment, StringComparison.OrdinalIgnoreCase)))
126+
commonSegments.Add(currentSegment);
127+
else
128+
break;
129+
}
130+
131+
if (commonSegments.Count == 0) return string.Empty;
132+
133+
string commonPath = string.Join("\\", commonSegments);
134+
return commonSegments[0].EndsWith(':') ? commonPath + "\\" : "\\" + commonPath;
111135
}
112-
catch (Exception ex)
136+
catch
113137
{
114-
_logger.Error(ex, "Error in LibraryVM_AudioFilesModifified handler");
138+
return string.Empty;
115139
}
116140
}
117141

142+
private string GetRelativePath(string fullPath, string rootPath)
143+
{
144+
if (string.IsNullOrEmpty(fullPath) || string.IsNullOrEmpty(rootPath))
145+
return fullPath;
146+
147+
string normalizedRoot = rootPath.EndsWith("\\") ? rootPath : rootPath + "\\";
148+
149+
return fullPath.StartsWith(normalizedRoot, StringComparison.OrdinalIgnoreCase)
150+
? fullPath[normalizedRoot.Length..]
151+
: fullPath;
152+
}
153+
118154
private void OnTextBoxPropertyChanged(object? sender, PropertyChangedEventArgs e)
119155
{
120156
if (e.PropertyName == nameof(ExportPath))
@@ -174,35 +210,27 @@ private void Export()
174210

175211
try
176212
{
177-
// Create export directory
178213
Directory.CreateDirectory(ExportPath);
179-
_logger.Debug($"Export directory created/verified: {ExportPath}");
180214

181-
// Generate filename
182215
string playlistFileName = IOManager.RemoveInvalidFileNameChars(_spotifyVM.PlaylistName) + ".m3u8";
183216
string fullPath = Path.Combine(ExportPath, playlistFileName);
184-
_logger.Debug($"Full export file path: {fullPath}");
185217

186-
// Build playlist content
187218
List<string> files = new()
188219
{
189220
"#EXTM3U",
190221
"#" + _spotifyVM.PlaylistName + ".m3u8"
191222
};
192223

193-
// Get selected tracks for export
194224
List<Track> selectedTracks = _spotifyVM.PlaylistTracks.Where(t => t.IsIncludedInExport).ToList();
195225
_logger.Info($"Exporting {selectedTracks.Count} out of {_spotifyVM.PlaylistTracks.Count} total tracks");
196226

197-
List<string> exportPaths = selectedTracks.Select(track =>
198-
ExportAsRelativ ? track.Path.Remove(0, _exportRoot.Length) : track.Path).ToList();
227+
List<string> exportPaths = selectedTracks.ConvertAll(track =>
228+
ExportAsRelativ ? GetRelativePath(track.Path, _exportRoot) : track.Path);
199229

200230
files.AddRange(exportPaths);
201-
202-
// Write the playlist file
203231
File.WriteAllLines(fullPath, files);
204-
_logger.Info($"Playlist exported successfully to: {fullPath}");
205232

233+
_logger.Info($"Playlist exported successfully to: {fullPath}");
206234
ExportIsVisible = true;
207235
}
208236
catch (Exception ex)
@@ -220,10 +248,7 @@ private void Browse()
220248

221249
try
222250
{
223-
FolderBrowserDialog folderBrowser = new()
224-
{
225-
ShowNewFolderButton = false
226-
};
251+
FolderBrowserDialog folderBrowser = new() { ShowNewFolderButton = false };
227252

228253
if (folderBrowser.ShowDialog() == DialogResult.OK)
229254
{
@@ -251,4 +276,4 @@ private void Browse()
251276
}
252277
}
253278
}
254-
}
279+
}

0 commit comments

Comments
 (0)