-
Notifications
You must be signed in to change notification settings - Fork 32
/
Matcher.cs
109 lines (87 loc) · 3.58 KB
/
Matcher.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
namespace SubRenamer.Core;
public record MatchItem(string Key, string Video, string Subtitle);
public static class Matcher
{
public static List<MatchItem> Execute(IReadOnlyList<MatchItem> inputItems)
=> Execute(inputItems, new MatcherOptions());
public static List<MatchItem> Execute(IReadOnlyList<MatchItem> inputItems, MatcherOptions options)
{
// Create new collection
List<MatchItem> result = [];
List<string> videoFiles = [];
List<string> subtitleFiles = [];
// Separate Video files and Subtitle files
inputItems.Where(x => !string.IsNullOrEmpty(x.Video)).ToList().ForEach(item =>
{
result.Add(new MatchItem("", item.Video, ""));
videoFiles.Add(item.Video);
});
inputItems.Where(x => !string.IsNullOrEmpty(x.Subtitle)).ToList().ForEach(item =>
{
result.Add(new MatchItem("", "", item.Subtitle));
subtitleFiles.Add(item.Subtitle);
});
// Return directly if only 1 video and 1 subtitle
if (videoFiles.Count == 1 && subtitleFiles.Count == 1)
return [new MatchItem("1", videoFiles[0], subtitleFiles[0])];
// Get file keys
var video2Keys = CalculateFileKeys(videoFiles, customRegex: options.VideoRegex);
var subtitle2Keys = CalculateFileKeys(subtitleFiles, customRegex: options.SubtitleRegex);
// Merge items with same filename
result = MatcherHelper.MergeSameFilenameItems(result);
// Apply keys
List<MatchItem> keyedItems = [];
foreach (var item in result)
{
if (item.Key != "")
{
keyedItems.Add(item);
continue;
}
string? k = null;
if (!string.IsNullOrEmpty(item.Video)) video2Keys.TryGetValue(item.Video, out k);
else if (!string.IsNullOrEmpty(item.Subtitle)) subtitle2Keys.TryGetValue(item.Subtitle, out k);
keyedItems.Add(new MatchItem(k ?? "", item.Video, item.Subtitle));
}
result = keyedItems;
// Merge items with same keys
result = MatcherHelper.MergeSameKeysItems(result);
// Sort
result = MatcherHelper.SortItemsByKeys(result);
// Move empty keys to last
result = MatcherHelper.MoveEmptyKeyItemsToLast(result);
return result;
}
private static Dictionary<string, string> CalculateFileKeys(IReadOnlyList<string> files, string? customRegex)
{
var result = new Dictionary<string, string>();
if (customRegex is null)
{
// Method 1. Auto Diff Algorithm
var filenames = files
.Select(Path.GetFileNameWithoutExtension)
.Where(x => !string.IsNullOrEmpty(x))
.Distinct()
.ToList();
// Diff filenames
var diff = MatcherDiff.GetDiffResult(filenames!);
MatcherLogger.Out.WriteLine("[Diff.GetDiffResult]\n\n {0}\n", (diff != null ? diff : "null"));
// Extract Match keys
foreach (var f in files)
{
result[f] = MatcherHelper.PatchKey(
MatcherDiff.ExtractMatchKeyByDiff(diff, Path.GetFileNameWithoutExtension(f)));
}
}
else
{
// Method 2. Custom Regex
foreach (var f in files)
{
result[f] = MatcherHelper.PatchKey(
MatcherHelper.ExtractMatchKeyRegex(customRegex, Path.GetFileName(f)));
}
}
return result;
}
}