diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolderCollection.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolderCollection.cs index 7eae065..8e3a538 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolderCollection.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolderCollection.cs @@ -15,6 +15,13 @@ return this.FirstOrDefault(x => x.Id == id); } - + /// + /// Фильтрация требуемых папок компендиума. + /// + /// + public CompendiumFolderCollection Filter() + { + return [.. this.FindAll(x => x.Type != CompendiumDocumentType.Actor)]; + } } } diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumSchemaBuilder.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumSchemaBuilder.cs index 48e906a..4aa2d59 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumSchemaBuilder.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumSchemaBuilder.cs @@ -35,6 +35,38 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium /// public Dictionary TypeSchemas = []; + private readonly string[] _equipmentTypes = ["equipment", "armor", "backpack", "consumable", "kit", "shield", "treasure", "weapon"]; + + private SchemaNode GetPackSchema(CompendiumFolder folder) + { + if (!PackSchemas.TryGetValue(folder, out SchemaNode? value)) + { + value = new SchemaNode() + { + Resolver = Resolver, + Path = folder.Name + }; + PackSchemas[folder] = value; + } + + return value; + } + + private SchemaNode GetTypeSchema(string key) + { + if (!TypeSchemas.TryGetValue(key, out SchemaNode? value)) + { + value = new SchemaNode() + { + Resolver = Resolver, + Path = key + }; + TypeSchemas[key] = value; + } + + return value; + } + /// /// Получение набора схем, к которым относится проверяемый объект. /// @@ -43,27 +75,16 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium /// protected List GetItemSchemas(CompendiumFolder folder, string? itemType) { - if (!PackSchemas.ContainsKey(folder)) - { - PackSchemas[folder] = new SchemaNode() - { - Resolver = Resolver, - Path = folder.Name - }; - } - var key = folder.Type.ToString() + (itemType is not null ? $".{itemType}" : ""); - if (!TypeSchemas.ContainsKey(key)) + if (_equipmentTypes.Contains(itemType)) { - TypeSchemas[key] = new SchemaNode() - { - Resolver = Resolver, - Path = key - }; + return [GetPackSchema(folder), GetTypeSchema(key), GetTypeSchema("Equipment")]; + } + else + { + return [GetPackSchema(folder), GetTypeSchema(key)]; } - - return [PackSchemas[folder], TypeSchemas[key]]; } /// @@ -161,14 +182,14 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium /// Сохраняемая схема. protected void SaveSchema(string dir, string name, SchemaNode schema) { - var invalids = System.IO.Path.GetInvalidFileNameChars(); + var invalids = Path.GetInvalidFileNameChars(); var fileName = string.Join("_", schema.Path.Split(invalids, StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.'); - var path = Path.Combine(dir, fileName + ".txt"); + var path = Path.Combine(dir, fileName + ".yaml"); var dirPath = Path.GetDirectoryName(path); - if (!Directory.Exists(dirPath)) + if (dirPath is not null && !Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } @@ -177,10 +198,16 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium schema.Beautify(); - writer.WriteLine(name); - writer.WriteLine($"Different values: {schema.Values}"); - writer.WriteLine("====================================="); - writer.Write(schema.ToString()); + writer.WriteLine(SchemaNode.FormatYaml(new Dictionary() + { + ["name"] = name, + ["values"] = schema.Values.ToString() + }, schema.Types[0].GetYamlData())); + + //writer.WriteLine(name); + //writer.WriteLine($"Different values: {schema.Values}"); + //writer.WriteLine("====================================="); + //writer.Write(schema.ToString()); } } } diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/CompendiumLoader.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/CompendiumLoader.cs index bd48d00..bb8468a 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/CompendiumLoader.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/CompendiumLoader.cs @@ -68,6 +68,8 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry ProcessPackFolders((JArray)innerFolders!, folder); } } + + Collection = Collection.Filter(); } /// diff --git a/Pf2eDataScrapper/Pf2eDataScrapper.csproj b/Pf2eDataScrapper/Pf2eDataScrapper.csproj index 72e34b2..a35f64e 100644 --- a/Pf2eDataScrapper/Pf2eDataScrapper.csproj +++ b/Pf2eDataScrapper/Pf2eDataScrapper.csproj @@ -1,6 +1,7 @@  + 13.0 Exe net8.0 enable @@ -10,6 +11,7 @@ + diff --git a/Pf2eDataScrapper/SchemaBuilder/SchemaNode.cs b/Pf2eDataScrapper/SchemaBuilder/SchemaNode.cs index f628d17..790339b 100644 --- a/Pf2eDataScrapper/SchemaBuilder/SchemaNode.cs +++ b/Pf2eDataScrapper/SchemaBuilder/SchemaNode.cs @@ -130,7 +130,7 @@ namespace Pf2eDataScrapper.SchemaBuilder var typeNames = Types.Select(t => t.GetTypeName()).ToList(); - return string.Join("|", typeNames); + return string.Join(" | ", typeNames); } /// @@ -139,24 +139,31 @@ namespace Pf2eDataScrapper.SchemaBuilder /// Строковое представление элемента. public override string ToString() { + var result = new Dictionary() { + ["type"] = GetTypeName(), + ["path"] = Path, + ["is_null"] = IsNullable ? "true" : "false", + ["values"] = Values.ToString() + }; + if (IsSimple) { - return Types[0].ToString(); + return FormatYaml(result, Types[0].GetYamlData()); } if (Types.Count == 0) { - return "empty"; + return FormatYaml(result, new() { ["is_empty"] = "true" }); } - List result = ["mixed"]; + List types = []; foreach (var type in Types) { - result.Add(AbstractSchemaType.Indent(type?.ToString() ?? "")); + types.Add(Indent(type?.ToString() ?? "")); } - return string.Join("\n" + AbstractSchemaType.Tab, result); + return FormatYaml(result, new() { ["types"] = "- " + string.Join("\r\n- ", types) }); } /// @@ -169,5 +176,68 @@ namespace Pf2eDataScrapper.SchemaBuilder type.Beautify(); } } + + + + /// + /// Отступ для строкового представления. + /// + public const string Tab = " "; + + /// + /// Предел количество отображаемых элементов. + /// + public const int ElementLimit = 10; + + /// + /// Увеличение отступа строки. + /// + /// Изменяемая строка. + /// Строка с добавленными отступами. + public static string Indent(string text) + { + return text.Replace("\r\n", "\r\n" + Tab); + } + + /// + /// Форматирование данных в YAML. + /// + /// Словарь данных. + /// Строка форматированных данных + public static string FormatYaml(params List> input) + { + var result = ""; + + foreach (var kvp in MergeDictionaries(input)) + { + var val = kvp.Value.Contains("\r\n") ? $"\r\n{Tab}{Indent(kvp.Value)}" : kvp.Value; + + result += $"{kvp.Key}: {val}\r\n"; + } + + return result.Trim(); + } + + public static Dictionary MergeDictionaries(params List> input) + { + var result = new Dictionary(); + + foreach (var item in input) + { + foreach (var kvp in item) + { + if (result.ContainsKey(kvp.Key)) + { + result[kvp.Key] = kvp.Value; + } + else + { + result.Add(kvp.Key, kvp.Value); + } + } + } + + return result; + } } } diff --git a/Pf2eDataScrapper/SchemaBuilder/Types/AbstractSchemaType.cs b/Pf2eDataScrapper/SchemaBuilder/Types/AbstractSchemaType.cs index 4bd4612..425ca39 100644 --- a/Pf2eDataScrapper/SchemaBuilder/Types/AbstractSchemaType.cs +++ b/Pf2eDataScrapper/SchemaBuilder/Types/AbstractSchemaType.cs @@ -47,33 +47,19 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types /// Строковое представоение типа элемента public abstract string GetTypeName(); + /// + /// Получение данных для форматирования в YAML. + /// + /// Словарь данных + public abstract Dictionary GetYamlData(); + /// /// Полное строковое представление элемента. /// /// Строковое представление элемента. public override string ToString() { - return $"{GetTypeName()} {{{Parent.Path}}}"; - } - - /// - /// Отступ для строкового представления. - /// - public const string Tab = " "; - - /// - /// Предел количество отображаемых элементов. - /// - public const int ElementLimit = 10; - - /// - /// Увеличение отступа строки. - /// - /// Изменяемая строка. - /// Строка с добавленными отступами. - public static string Indent(string text) - { - return text.Replace("\n", "\n" + Tab); + return SchemaNode.FormatYaml(GetYamlData()); } } } \ No newline at end of file diff --git a/Pf2eDataScrapper/SchemaBuilder/Types/ArraySchemaType.cs b/Pf2eDataScrapper/SchemaBuilder/Types/ArraySchemaType.cs index 896cc30..3f66376 100644 --- a/Pf2eDataScrapper/SchemaBuilder/Types/ArraySchemaType.cs +++ b/Pf2eDataScrapper/SchemaBuilder/Types/ArraySchemaType.cs @@ -73,16 +73,17 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types } /// - /// Полное строковое представление элемента. + /// Получение данных для форматирования в YAML. /// - /// Строковое представление элемента. - public override string ToString() + /// Словарь данных + public override Dictionary GetYamlData() { - return string.Join("\n" + Tab, [ - base.ToString(), - $"Length: min={MinCount} max={MaxCount}", - "Value type: " + Indent(ElementSchema.ToString()) - ]); + return new() + { + ["min_count"] = MinCount.ToString(), + ["max_count"] = MaxCount.ToString(), + ["value_type"] = ElementSchema.ToString() + }; } } } diff --git a/Pf2eDataScrapper/SchemaBuilder/Types/DictionarySchemaType.cs b/Pf2eDataScrapper/SchemaBuilder/Types/DictionarySchemaType.cs index fb3e008..3c76338 100644 --- a/Pf2eDataScrapper/SchemaBuilder/Types/DictionarySchemaType.cs +++ b/Pf2eDataScrapper/SchemaBuilder/Types/DictionarySchemaType.cs @@ -62,16 +62,16 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types } /// - /// Полное строковое представление элемента. + /// Получение данных для форматирования в YAML. /// - /// Строковое представление элемента. - public override string ToString() + /// Словарь данных + public override Dictionary GetYamlData() { - return string.Join("\n" + Tab, [ - base.ToString(), - "#key : " + Indent(KeyNode.ToString()), - "#value : " + Indent(ItemNode.ToString()) - ]); + return new Dictionary() + { + ["_key"] = KeyNode.ToString(), + ["_value"] = ItemNode.ToString() + }; } } } diff --git a/Pf2eDataScrapper/SchemaBuilder/Types/IgnoreSchemaType.cs b/Pf2eDataScrapper/SchemaBuilder/Types/IgnoreSchemaType.cs index d5d7605..df025cd 100644 --- a/Pf2eDataScrapper/SchemaBuilder/Types/IgnoreSchemaType.cs +++ b/Pf2eDataScrapper/SchemaBuilder/Types/IgnoreSchemaType.cs @@ -41,5 +41,15 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types { return "ignore"; } + + + /// + /// Получение данных для форматирования в YAML. + /// + /// Словарь данных + public override Dictionary GetYamlData() + { + return []; + } } } diff --git a/Pf2eDataScrapper/SchemaBuilder/Types/ObjectSchemaType.cs b/Pf2eDataScrapper/SchemaBuilder/Types/ObjectSchemaType.cs index dd71bd9..5dc3780 100644 --- a/Pf2eDataScrapper/SchemaBuilder/Types/ObjectSchemaType.cs +++ b/Pf2eDataScrapper/SchemaBuilder/Types/ObjectSchemaType.cs @@ -84,26 +84,39 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types } /// - /// Полное строковое представление элемента. + /// Получение данных для форматирования структуры в YAML. /// - /// Строковое представление элемента. - public override string ToString() + /// Словарь данных + public Dictionary GetSchemaYaml() { - List rows = [base.ToString()]; + var result = new Dictionary(); foreach (var field in Fields) { var s = field.Name; - if (field.IsNullable) { s = $"[{s}]"; } - - rows.Add(Indent(s + " : " + field.ToString())); + else + { + s = $"'{s}'"; + } + result.Add(s, field.ToString()); } - return string.Join("\n" + Tab, rows); + return result; + } + + /// + /// Получение данных для форматирования в YAML. + /// + /// Словарь данных + public override Dictionary GetYamlData() + { + return new() { + ["schema"] = SchemaNode.FormatYaml(GetSchemaYaml()) + }; } } diff --git a/Pf2eDataScrapper/SchemaBuilder/Types/StaticSchemaType.cs b/Pf2eDataScrapper/SchemaBuilder/Types/StaticSchemaType.cs index d750709..dd587c8 100644 --- a/Pf2eDataScrapper/SchemaBuilder/Types/StaticSchemaType.cs +++ b/Pf2eDataScrapper/SchemaBuilder/Types/StaticSchemaType.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json.Linq; +using System.Linq.Expressions; +using Newtonsoft.Json.Linq; namespace Pf2eDataScrapper.SchemaBuilder.Types { @@ -51,7 +52,7 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types foreach (var pair in Values) { - var newValue = "'" + pair.Key.ToString().Trim().Replace("'", "\\'") + "'"; + var newValue = "\"" + pair.Key.ToString().Trim().Replace("\"", "\\\"") + "\""; newValues.TryAdd(newValue, 0); newValues[newValue] += pair.Value; } @@ -72,37 +73,30 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types } /// - /// Полное строковое представление элемента. + /// Получение данных для форматирования в YAML. /// - /// Строковое представление элемента. - public override string ToString() + /// Словарь данных + public override Dictionary GetYamlData() { - var result = base.ToString(); + var values = new List(); var count = Values.Count; - if (count == Root.Values) + var prefix = (count == 1) ? "" : "- "; + + if (count is <= SchemaNode.ElementLimit and > 0 && (Type != JTokenType.String || !Values.Any(s => s.ToString().Contains('\n')))) { - result += " (all different values)"; - return result; + foreach (var kvp in Values) + { + values.Add($"{prefix}{kvp.Key} (x{kvp.Value})"); + } } - if (count == 1) - { - result += $" (same value: {Values.Keys.ToList()[0]})"; - return result; - } - - result += $" ({count} different values)"; - - if (count is > ElementLimit or <= 0 || (Type == JTokenType.String && Values.Any(s => s.ToString().Contains('\n')))) - { - return result.Trim(); - } - - result += "\n"; - result = Values.Aggregate(result, (current, value) => current + $"{Tab}{value.Key} (x{value.Value})\n"); - - return result.Trim(); + return new() { + ["different_values"] = count.ToString() + + ((count == Root.Values) ? " (all different)" : "") + + ((count == 1) ? " (all same)" : ""), + ["variants"] = (values.Count > 0) ? string.Join("\r\n", values) : "[omitted]" + }; } } }