diff --git a/Component/MainTreePanel.cs b/Component/MainTreePanel.cs index 47a774e..2468ff7 100644 --- a/Component/MainTreePanel.cs +++ b/Component/MainTreePanel.cs @@ -38,7 +38,7 @@ public partial class MainTreePanel : Tree SetColumnTitlesVisible(true); SetColumnTitle(0, "文件名"); - SetColumnCustomMinimumWidth(0, 500); + SetColumnCustomMinimumWidth(0, 800); SetColumnExpand(0, true); MultiSelected += OnMultiSelected; diff --git a/Config/AppConfig.cs b/Config/AppConfig.cs index 921a05a..cea4e42 100644 --- a/Config/AppConfig.cs +++ b/Config/AppConfig.cs @@ -5,5 +5,5 @@ namespace Learn.Config; [ConfigItem("APP")] public class AppConfig : IConfigItem { - public string ScanPath = ""; + public string ScanPath { get; set; } = ""; } \ No newline at end of file diff --git a/Config/AppConfig.cs.uid b/Config/AppConfig.cs.uid new file mode 100644 index 0000000..e8b619e --- /dev/null +++ b/Config/AppConfig.cs.uid @@ -0,0 +1 @@ +uid://bakkudpxylhe8 diff --git a/Config/ProxyConfig.cs b/Config/ProxyConfig.cs deleted file mode 100644 index 9c1d178..0000000 --- a/Config/ProxyConfig.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Learn.Utils; - -namespace Learn.Config; - -[ConfigItem("Proxy")] -public class ProxyConfig : IConfigItem -{ - public string HttpProxy = ""; -} \ No newline at end of file diff --git a/Config/ProxyConfig.cs.uid b/Config/ProxyConfig.cs.uid deleted file mode 100644 index db66392..0000000 --- a/Config/ProxyConfig.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://k75xslv0u3pm diff --git a/Config/RawParserConfig.cs b/Config/RawParserConfig.cs new file mode 100644 index 0000000..74513aa --- /dev/null +++ b/Config/RawParserConfig.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using Learn.Utils; + +namespace Learn.Config; + +public class MatchGroupsRules +{ + public List Full { get; set; } + public List Partial { get; set; } +} + + +public class MatchTypeExtra +{ + public List IfDirNameIs { get; set; } + public List IfFileExtensionIs { get; set; } +} + +public class MatchTypeSubtitle +{ + public List IfFileExtensionIs { get; set; } +} + +public class MatchTypeEpisode +{ + public List IfFileExtensionIs { get; set; } +} + +public class MatchTypeRules +{ + public MatchTypeExtra Extra { get; set; } + public MatchTypeSubtitle Subtitle { get; set; } + public MatchTypeEpisode Episode { get; set; } +} + +public class MatchSeasonRules +{ + public List Regexes { get; set; } +} + +public class FilterTokenRules +{ + public List Regexes { get; set; } +} + +[ConfigItem("RawParser")] +public class RawParserConfig : IConfigItem +{ + public string SplitRegex { get; set; } = ""; + + public MatchTypeRules TypeMatchRules { get; set; } + + public MatchGroupsRules GroupsMatchRules { get; set; } + + public MatchSeasonRules SeasonMatchRules { get; set; } + + public FilterTokenRules TokenFilterRules { get; set; } +} \ No newline at end of file diff --git a/Config/RawParserConfig.cs.uid b/Config/RawParserConfig.cs.uid new file mode 100644 index 0000000..95c9aa8 --- /dev/null +++ b/Config/RawParserConfig.cs.uid @@ -0,0 +1 @@ +uid://ccldbt2fp1mxn diff --git a/Config/TMDBConfig.cs b/Config/TMDBConfig.cs deleted file mode 100644 index bde84e2..0000000 --- a/Config/TMDBConfig.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Learn.Utils; - -namespace Learn.Config; - -[ConfigItem("TMDB")] -public class TMDBConfig : IConfigItem -{ - public string ApiKey = ""; -} \ No newline at end of file diff --git a/Config/TMDBConfig.cs.uid b/Config/TMDBConfig.cs.uid deleted file mode 100644 index 905f30b..0000000 --- a/Config/TMDBConfig.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://v07s3j12o0lw diff --git a/Config/TMDBParserConfig.cs b/Config/TMDBParserConfig.cs new file mode 100644 index 0000000..7035e79 --- /dev/null +++ b/Config/TMDBParserConfig.cs @@ -0,0 +1,10 @@ +using Learn.Utils; + +namespace Learn.Config; + +[ConfigItem("TMDBParser")] +public class TMDBParserConfig : IConfigItem +{ + public string HttpProxy { get; set; } = ""; + public string ApiKey { get; set; } = ""; +} \ No newline at end of file diff --git a/Config/TMDBParserConfig.cs.uid b/Config/TMDBParserConfig.cs.uid new file mode 100644 index 0000000..1edc9bf --- /dev/null +++ b/Config/TMDBParserConfig.cs.uid @@ -0,0 +1 @@ +uid://dp5xqvvuiclbg diff --git a/Learn.sln.DotSettings.user b/Learn.sln.DotSettings.user index 64a225a..f19465e 100644 --- a/Learn.sln.DotSettings.user +++ b/Learn.sln.DotSettings.user @@ -1,4 +1,5 @@  + ForceIncluded ForceIncluded ForceIncluded ForceIncluded diff --git a/Main.cs b/Main.cs index b915538..65d935d 100644 --- a/Main.cs +++ b/Main.cs @@ -21,6 +21,7 @@ public partial class Main : Node [Export] private Button _saveButton; [Export] private Button _resetButton; [Export] private Button _loadButton; + [Export] private Button _reloadConfigButton; [ExportGroup("编辑面板")] [Export] private NodeInfoEditPanel _nodeInfoEditPanel; @@ -70,6 +71,7 @@ public partial class Main : Node _saveButton.Pressed += DoSave; _resetButton.Pressed += DoReset; _loadButton.Pressed += LoadData; + _reloadConfigButton.Pressed += ReloadConfig; _doParseButton.Text = "开始解析"; _configs = new Configs(); @@ -82,6 +84,11 @@ public partial class Main : Node _refreshPanels = true; } + private void ReloadConfig() + { + _configs.Load(true); + } + private void LoadData() { if (File.Exists(DataPath)) @@ -146,7 +153,7 @@ public partial class Main : Node var originName = _doParseButton.Text; _doParseButton.Disabled = true; - ItemParser parser = new RawParser(); + ItemParser parser = new RawParser(_configs); if (_mainTreePanel.Query(root, out var node)) { diff --git a/MediaTreeEditor.tscn b/MediaTreeEditor.tscn index aa311b5..ed06399 100644 --- a/MediaTreeEditor.tscn +++ b/MediaTreeEditor.tscn @@ -17,7 +17,7 @@ grow_vertical = 2 [node name="FileDirDialog" type="FileDialog" parent="."] script = ExtResource("1_d2g23") -[node name="Main" type="Node" parent="." node_paths=PackedStringArray("_dirSelector", "_openDirButton", "_doParseButton", "_saveButton", "_resetButton", "_loadButton", "_nodeInfoEditPanel", "_addKeyButton", "_removeKeyButton", "_inspectorPanel", "_mainTreePanel", "_columnIndexText", "_columnWidthText", "_columnText", "_addColumnButton", "_removeColumnButton", "_clearColumnButton", "_expandAllButton", "_foldAllButton")] +[node name="Main" type="Node" parent="." node_paths=PackedStringArray("_dirSelector", "_openDirButton", "_doParseButton", "_saveButton", "_resetButton", "_loadButton", "_reloadConfigButton", "_nodeInfoEditPanel", "_addKeyButton", "_removeKeyButton", "_inspectorPanel", "_mainTreePanel", "_columnIndexText", "_columnWidthText", "_columnText", "_addColumnButton", "_removeColumnButton", "_clearColumnButton", "_expandAllButton", "_foldAllButton")] script = ExtResource("2_0727o") _dirSelector = NodePath("../FileDirDialog") _openDirButton = NodePath("../MarginContainer/HSplitContainer/ScrollContainer/VBoxContainer2/FoldableContainer4/VBoxContainer2/TabContainer/文件夹操作/ScanDir") @@ -25,6 +25,7 @@ _doParseButton = NodePath("../MarginContainer/HSplitContainer/ScrollContainer/VB _saveButton = NodePath("../MarginContainer/HSplitContainer/ScrollContainer/VBoxContainer2/FoldableContainer4/VBoxContainer2/TabContainer/保存操作/Save") _resetButton = NodePath("../MarginContainer/HSplitContainer/ScrollContainer/VBoxContainer2/FoldableContainer4/VBoxContainer2/TabContainer/保存操作/Reset") _loadButton = NodePath("../MarginContainer/HSplitContainer/ScrollContainer/VBoxContainer2/FoldableContainer4/VBoxContainer2/TabContainer/保存操作/Load") +_reloadConfigButton = NodePath("../MarginContainer/HSplitContainer/ScrollContainer/VBoxContainer2/FoldableContainer4/VBoxContainer2/TabContainer/保存操作/ReloadConfig") _nodeInfoEditPanel = NodePath("../MarginContainer/HSplitContainer/ScrollContainer/VBoxContainer2/FoldableContainer/VBoxContainer/NodeEditPanel") _addKeyButton = NodePath("../MarginContainer/HSplitContainer/ScrollContainer/VBoxContainer2/FoldableContainer/VBoxContainer/HBoxContainer/AddKey") _removeKeyButton = NodePath("../MarginContainer/HSplitContainer/ScrollContainer/VBoxContainer2/FoldableContainer/VBoxContainer/HBoxContainer/RemoveKey") @@ -85,9 +86,10 @@ layout_mode = 2 [node name="TabContainer" type="TabContainer" parent="MarginContainer/HSplitContainer/ScrollContainer/VBoxContainer2/FoldableContainer4/VBoxContainer2"] custom_minimum_size = Vector2(0, 200) layout_mode = 2 -current_tab = 0 +current_tab = 1 [node name="文件夹操作" type="VBoxContainer" parent="MarginContainer/HSplitContainer/ScrollContainer/VBoxContainer2/FoldableContainer4/VBoxContainer2/TabContainer"] +visible = false layout_mode = 2 metadata/_tab_index = 0 @@ -102,7 +104,6 @@ size_flags_vertical = 4 text = "开始解析" [node name="保存操作" type="VBoxContainer" parent="MarginContainer/HSplitContainer/ScrollContainer/VBoxContainer2/FoldableContainer4/VBoxContainer2/TabContainer"] -visible = false layout_mode = 2 metadata/_tab_index = 1 @@ -118,6 +119,10 @@ text = "加载树表" layout_mode = 2 text = "重置树表" +[node name="ReloadConfig" type="Button" parent="MarginContainer/HSplitContainer/ScrollContainer/VBoxContainer2/FoldableContainer4/VBoxContainer2/TabContainer/保存操作"] +layout_mode = 2 +text = "重载配置" + [node name="树表操作" type="VBoxContainer" parent="MarginContainer/HSplitContainer/ScrollContainer/VBoxContainer2/FoldableContainer4/VBoxContainer2/TabContainer"] visible = false layout_mode = 2 diff --git a/Models/TreeNode.cs b/Models/TreeNode.cs index f409fe7..e029adc 100644 --- a/Models/TreeNode.cs +++ b/Models/TreeNode.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace Learn.Models; @@ -28,47 +29,45 @@ public class TreeNode(Item item) public bool TryGetValue(string key, out string value, out bool isInherited) { + value = null; + isInherited = false; var curr = this; - + + bool valueExists = false; while (curr.Info != null) { - if (curr.Info.Info.TryGetValue(key, out value)) + if (curr.Info.Info.TryGetValue(key, out var currValue)) { - isInherited = curr != this; - return true; + value = currValue; + valueExists = true; + isInherited = (curr != this); } curr = curr.Parent; } - - value = null; - isInherited = false; - return false; + + return valueExists; } public IEnumerable GetKeyValueInfos() { - var result = new List(); - var keys = new HashSet(); + var dict = new Dictionary(); var curr = this; while (curr.Info != null) { foreach (var kv in curr.Info.Info) { - if(!keys.Add(kv.Key)) continue; - var keyValueInfo = new KeyValueInfo(); - - if (curr != this) + var keyValueInfo = new KeyValueInfo { - keyValueInfo.IsInherited = true; - } - - keyValueInfo.Key = kv.Key; - keyValueInfo.Value = kv.Value; - result.Add(keyValueInfo); + IsInherited = curr != this, + Key = kv.Key, + Value = kv.Value + }; + + dict[kv.Key] = keyValueInfo; } curr = curr.Parent; } - return result; + return dict.Values.ToList(); } } \ No newline at end of file diff --git a/Parsers/ItemFields.cs b/Parsers/ItemFields.cs index 68d5312..73d31b1 100644 --- a/Parsers/ItemFields.cs +++ b/Parsers/ItemFields.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.IO; using Learn.Models; @@ -6,6 +7,14 @@ namespace Learn.Parsers; public static class ItemFields { + public enum ItemType + { + Unknown, + Extra, + Subtitle, + Episode + } + #region 基础信息 public static string MainKey_Path => "Path"; @@ -25,36 +34,27 @@ public static class ItemFields #endregion + #region 普通字段 public static string Key_Group => "Group"; public static string Key_Title => "Title"; public static string Key_RawTitle => "RawTitle"; public static string Key_Season => "Season"; - public static string Key_Year => "Year"; + public static string Key_Type => "Type"; + public static string Key_SubtitleLanguage => "SubLang"; + + public static ItemType Type(this Item item) + { + if (item.Info.TryGetValue(Key_Type, out var typeName)) + { + if(Enum.TryParse(typeName, out ItemType type)) + { + return type; + } + } + return ItemType.Unknown; + } - public static void SetGroupIfNotExist(this Item item, string group) - { - item.Info.TryAdd(Key_Group, group); - } - - public static void SetTitleIfNotExist(this Item item, string title) - { - item.Info.TryAdd(Key_Title, title); - } - - public static void SetRawTitleIfNotExist(this Item item, string rawTitle) - { - item.Info.TryAdd(Key_RawTitle, rawTitle); - } - - public static void SetSeasonIfNotExist(this Item item, string season) - { - item.Info.TryAdd(Key_Season, season); - } - - public static void SetYear(this Item item, int year) - { - item.Info[Key_Year] = year.ToString(); - } + #endregion } \ No newline at end of file diff --git a/Parsers/ItemParser.cs b/Parsers/ItemParser.cs index 00e9a6d..46b57ab 100644 --- a/Parsers/ItemParser.cs +++ b/Parsers/ItemParser.cs @@ -12,7 +12,6 @@ namespace Learn.Parsers; /// "集数" /// "类型":"额外内容", "字幕", "剧集" /// "字幕语言" -/// "年份" /// public interface ItemParser { diff --git a/Parsers/RawParser.cs b/Parsers/RawParser.cs index 7cdebac..17c8d6c 100644 --- a/Parsers/RawParser.cs +++ b/Parsers/RawParser.cs @@ -1,135 +1,321 @@ +using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Learn.Config; using Learn.Models; +using Learn.Utils; namespace Learn.Parsers; -public class RawParser : ItemParser +public class RawParser(Configs configs) : ItemParser { - private string ParseSeasonFromCN(string season) - { - if (int.TryParse(season, out _)) return season; - - switch (season) - { - case "零": return "0"; - case "一": return "1"; - case "二": return "2"; - case "三": return "3"; - case "四": return "4"; - case "五": return "5"; - case "六": return "6"; - case "七": return "7"; - case "八": return "8"; - case "九": return "9"; - } - return season; - } - - - private (string, string) SplitTitleAndSeason(string rawTitle) - { - var match1 = Regex.Match(rawTitle, @"第(.+)季"); - if (match1.Success) - { - var seasonStr = match1.Groups[0].Value.Trim(); - var season = ParseSeasonFromCN(match1.Groups[1].Value.Trim()); - var title = rawTitle.Replace(seasonStr, "").Trim(); - return (title, season); - } - - var match2 = Regex.Match(rawTitle, @"[Ss]eason *(\d+)"); - if (match2.Success) - { - var seasonStr = match1.Groups[0].Value.Trim(); - var season = int.Parse(match1.Groups[1].Value.Trim()).ToString(); - var title = rawTitle.Replace(seasonStr, "").Trim(); - return (title, season); - } + private RawParserConfig config => configs.Get(); - return (rawTitle, null); + private List FilterParts(List parts) + { + var result = parts.ToList(); + foreach (var regex in config.TokenFilterRules.Regexes) + { + result.RemoveAll(part => Regex.Match(part.Trim(), regex).Success); + } + return result; } - private void SimplifyMatches(List matches) + private List GetParts(Item item) { - matches.RemoveAll(match => string.IsNullOrEmpty(match.Trim())); - matches.RemoveAll(match => Regex.Match(match.Trim(), @"\d+[Pp]$").Success); + var matches = Regex.Matches(item.Name(), config.SplitRegex).Select(match => match.Value) + .Select(match => match.Trim()) + .Where(match => !string.IsNullOrEmpty(match)) + .ToList(); + return FilterParts(matches); } - private List GetParts(string name) - { - var matches = Regex.Matches(name, @"[^\[\]_【】]+").Select(match => match.Value).ToList(); - SimplifyMatches(matches); - return matches; - } - - private bool TryParseRawTitle(Item item, out string rawTitle) - { - rawTitle = null; - var name = item.Name(); - var matches = GetParts(name); - - if (matches.Count == 0) return false; - - if (matches.Count == 1) - { - rawTitle = matches[0]; - } - else - { - rawTitle = matches[1]; - } - - (rawTitle, _) = SplitTitleAndSeason(rawTitle); - return true; - } - - private bool TryParseSeason(Item item, out string season) + private bool TryNormalizeSeason(string seasonPart, out string season) { season = null; - var name = item.Name(); - var matches = GetParts(name); - - if (matches.Count == 0) return false; - - if (matches.Count == 1) + if (int.TryParse(seasonPart, out var seasonInt)) { - (_, season) = SplitTitleAndSeason(matches[0]); - if (!string.IsNullOrEmpty(season)) return true; + season = seasonInt.ToString(); + return true; } - else + switch (seasonPart) { - (_, season) = SplitTitleAndSeason(matches[1]); - if (!string.IsNullOrEmpty(season)) return true; + case "零": + season = "0"; + return true; + case "一": + season = "1"; + return true; + case "二": + season = "2"; + return true; + case "三": + season = "3"; + return true; + case "四": + season = "4"; + return true; + case "五": + season = "5"; + return true; + case "六": + season = "6"; + return true; + case "七": + season = "7"; + return true; + case "八": + season = "8"; + return true; + case "九": + season = "9"; + return true; + } + return false; + } + + private bool TryMatchSeason(string token, out string seasonPart, out string matchPart) + { + seasonPart = null; + matchPart = null; + + var regexes = config.SeasonMatchRules?.Regexes; + if (regexes == null) return false; + + token = token.Trim(); + + foreach (var regex in regexes) + { + var match = Regex.Match(token, regex); + if (!match.Success) continue; + matchPart = match.Value; + return TryNormalizeSeason(match.Groups[1].Value, out seasonPart); + } + return false; + } + + private bool TryParseSeason(TreeNode node, out string season, out MatchInfo matchInfo) + { + season = null; + matchInfo = null; + + var parts = GetParts(node.Info); + for (int i = 0; i < parts.Count; i++) + { + var part = parts[i]; + var tokens = part.Split("-"); + foreach (var token in tokens) + { + if (!TryMatchSeason(token, out season, out var content)) continue; + matchInfo = new MatchInfo + { + content = content, + partIndex = i + }; + return true; + } } return false; } - private bool TryParseGroup(Item item, out string group) + private bool IsFullMatch(string item, List sequence) + { + if(sequence == null) return false; + for (int i = 0; i < sequence.Count; i++) + { + if (item.Equals(sequence[i], StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + return false; + } + + private bool IsPartialMatch(string item, List sequence) + { + if(sequence == null) return false; + for (int i = 0; i < sequence.Count; i++) + { + if (item.Contains(sequence[i], StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + return false; + } + + private bool TryParseGroup(TreeNode node, out string group, out MatchInfo matchInfo) { group = null; - var name = item.Name(); - var matches = GetParts(name); + matchInfo = null; + + var parts = GetParts(node.Info); + for (int i = 0; i < parts.Count; i++) + { + if (IsFullMatch(parts[i], config.GroupsMatchRules?.Full)) + { + group = parts[i]; + matchInfo = new MatchInfo + { + content = parts[i], + partIndex = i + }; + return true; + } + } + + for (int i = 0; i < parts.Count; i++) + { + if (IsPartialMatch(parts[i], config.GroupsMatchRules?.Partial)) + { + group = parts[i]; + matchInfo = new MatchInfo + { + content = parts[i], + partIndex = i + }; + return true; + } + } + return false; + } - if (matches.Count <= 1) return false; - group = matches[0]; + private ItemFields.ItemType ParseItemType(TreeNode node) + { + // 1. 判断是否属于Extras + foreach (var extraMatchName in config.TypeMatchRules.Extra.IfDirNameIs) + { + if (node.Info.Name().Equals(extraMatchName, StringComparison.OrdinalIgnoreCase)) + { + return ItemFields.ItemType.Extra; + } + } + + if (node.Info.IsFolder()) + { + return ItemFields.ItemType.Unknown; + } + + var infoExt = Path.GetExtension(node.Info.Name()); + if (string.IsNullOrEmpty(infoExt)) return ItemFields.ItemType.Extra; + foreach (var ext in config.TypeMatchRules.Extra.IfFileExtensionIs) + { + if (infoExt.Equals(ext, StringComparison.OrdinalIgnoreCase)) + { + return ItemFields.ItemType.Extra; + } + } + + // 2. 判断是不是字幕 + foreach (var ext in config.TypeMatchRules.Subtitle.IfFileExtensionIs) + { + if (infoExt.Equals(ext, StringComparison.OrdinalIgnoreCase)) + { + return ItemFields.ItemType.Subtitle; + } + } + + // 3. 判断是不是剧集 + foreach (var ext in config.TypeMatchRules.Episode.IfFileExtensionIs) + { + if (infoExt.Equals(ext, StringComparison.OrdinalIgnoreCase)) + { + return ItemFields.ItemType.Episode; + } + } + + // 4. 啥都不是,不知道 + return ItemFields.ItemType.Unknown; + } + + private bool TryParseType(TreeNode node, out string type, out MatchInfo matchInfo) + { + matchInfo = null; + type = null; + var typeEnum = ParseItemType(node); + if (typeEnum == ItemFields.ItemType.Unknown) return false; + type = typeEnum.ToString(); return true; } + + private bool TryParseSubtitleLanguage(TreeNode node, out string language, out MatchInfo matchInfo) + { + language = null; + matchInfo = null; + if (node.Info.Type() != ItemFields.ItemType.Subtitle) + { + return false; + } + var name = node.Info.Name(); + var parts = name.Split("."); + if (parts.Length < 3) return false; + + language = parts[^2]; + return true; + } + + private bool TryParseEpisode(TreeNode node, out string episode, out MatchInfo matchInfo) + { + episode = null; + matchInfo = null; + if (node.Info.Type() != ItemFields.ItemType.Episode) + { + return false; + } + + var parts = GetParts(node.Info); + for (int i = 0; i < parts.Count; i++) + { + var part = parts[i]; + var tokens = part.Split("-"); + foreach (var token in tokens) + { + var match = Regex.Match(token.Trim(), @"^\d{1,2}$"); + if (match.Success) + { + matchInfo = new MatchInfo + { + content = content, + partIndex = i + }; + } + + return true; + } + } + + return false; + } - private delegate bool FieldParser(Item item, out string result); + // + // private bool TryParseRawTitle(TreeNode node, out string rawTitle, out MatchInfo matchInfo) + // { + // + // } + + + class MatchInfo + { + public string content; + public int partIndex; + } + + private delegate bool FieldParser(TreeNode node, out string result, out MatchInfo matchInfo); private bool TryParseField(TreeNode node, FieldParser fieldParser, out string result) { result = null; if (node.Info == null) return false; - if (!fieldParser(node.Info, out var fieldValue)) return false; + + if (!fieldParser(node, out var fieldValue, out _)) return false; var parsed = new List(); foreach (var child in node.Children) { - if (fieldParser(child.Info, out var childFieldValue)) + if (fieldParser(child, out var childFieldValue, out _)) { parsed.Add(childFieldValue); } @@ -162,6 +348,7 @@ public class RawParser : ItemParser while (queue.Count > 0) { var current = queue.Dequeue(); + if(current.Info.Info.ContainsKey(fieldName)) continue; if (TryParseField(current, fieldParser, out var fieldValue)) { current.Info.Info.TryAdd(fieldName, fieldValue); @@ -178,8 +365,10 @@ public class RawParser : ItemParser public async Task Parse(TreeNode node) { - DoParse(node, TryParseRawTitle, ItemFields.Key_RawTitle); DoParse(node, TryParseSeason, ItemFields.Key_Season); DoParse(node, TryParseGroup, ItemFields.Key_Group); + DoParse(node, TryParseType, ItemFields.Key_Type); + DoParse(node, TryParseSubtitleLanguage, ItemFields.Key_SubtitleLanguage); + } } \ No newline at end of file diff --git a/Parsers/TMDBParser.cs b/Parsers/TMDBParser.cs index 0eb60b8..b361506 100644 --- a/Parsers/TMDBParser.cs +++ b/Parsers/TMDBParser.cs @@ -14,6 +14,8 @@ namespace Learn.Parsers; public class TMDBParser(Configs configs) : ItemParser { + private TMDBParserConfig config => configs.Get(); + private readonly Dictionary _cache = new(); private TMDbClient _client; @@ -37,8 +39,8 @@ public class TMDBParser(Configs configs) : ItemParser { if (_client != null) return _client; - var apiKey = configs.Get().ApiKey; - var proxy = configs.Get().HttpProxy; + var apiKey = config.ApiKey; + var proxy = config.HttpProxy; if (string.IsNullOrEmpty(proxy)) { @@ -48,7 +50,7 @@ public class TMDBParser(Configs configs) : ItemParser { _client = new TMDbClient(apiKey , proxy: new WebProxy(proxy)); } - + return _client; } diff --git a/project.godot b/project.godot index a8abf3a..6bc9f78 100644 --- a/project.godot +++ b/project.godot @@ -17,8 +17,8 @@ config/icon="res://icon.svg" [display] -window/size/viewport_width=1920 -window/size/viewport_height=1080 +window/size/viewport_width=1600 +window/size/viewport_height=900 [dotnet]