diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..b075827
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,267 @@
+# Удалите строку ниже, если вы хотите наследовать параметры .editorconfig из каталогов, расположенных выше в иерархии
+root = true
+
+# Файлы C#
+[*.cs]
+
+#### Основные параметры EditorConfig ####
+
+# Отступы и интервалы
+indent_size = 4
+indent_style = space
+tab_width = 4
+
+# Предпочтения для новых строк
+end_of_line = crlf
+insert_final_newline = false
+
+#### Действия кода .NET ####
+
+# Члены типа
+dotnet_hide_advanced_members = false
+dotnet_member_insertion_location = with_other_members_of_the_same_kind
+dotnet_property_generation_behavior = prefer_throwing_properties
+
+# Поиск символов
+dotnet_search_reference_assemblies = true
+
+#### Рекомендации по написанию кода .NET ####
+
+# Упорядочение Using
+dotnet_separate_import_directive_groups = false
+dotnet_sort_system_directives_first = false
+file_header_template = unset
+
+# Предпочтения для this. и Me.
+dotnet_style_qualification_for_event = false
+dotnet_style_qualification_for_field = false
+dotnet_style_qualification_for_method = false
+dotnet_style_qualification_for_property = false
+
+# Параметры использования ключевых слов языка и типов BCL
+dotnet_style_predefined_type_for_locals_parameters_members = true
+dotnet_style_predefined_type_for_member_access = true
+
+# Предпочтения для скобок
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary
+dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
+
+# Предпочтения модификатора
+dotnet_style_require_accessibility_modifiers = for_non_interface_members
+
+# Выражения уровень предпочтения
+dotnet_prefer_system_hash_code = true
+dotnet_style_coalesce_expression = true
+dotnet_style_collection_initializer = true
+dotnet_style_explicit_tuple_names = true
+dotnet_style_namespace_match_folder = true
+dotnet_style_null_propagation = true
+dotnet_style_object_initializer = true
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+dotnet_style_prefer_auto_properties = true
+dotnet_style_prefer_collection_expression = when_types_loosely_match
+dotnet_style_prefer_compound_assignment = true
+dotnet_style_prefer_conditional_expression_over_assignment = true
+dotnet_style_prefer_conditional_expression_over_return = true
+dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
+dotnet_style_prefer_inferred_anonymous_type_member_names = true
+dotnet_style_prefer_inferred_tuple_names = true
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true
+dotnet_style_prefer_simplified_boolean_expressions = true
+dotnet_style_prefer_simplified_interpolation = true
+
+# Предпочтения для полей
+dotnet_style_readonly_field = true
+
+# Настройки параметров
+dotnet_code_quality_unused_parameters = all
+
+# Параметры подавления
+dotnet_remove_unnecessary_suppression_exclusions = none
+
+# Предпочтения для новых строк
+dotnet_style_allow_multiple_blank_lines_experimental = true
+dotnet_style_allow_statement_immediately_after_block_experimental = true
+
+#### Рекомендации по написанию кода C# ####
+
+# Предпочтения var
+csharp_style_var_elsewhere = false
+csharp_style_var_for_built_in_types = false
+csharp_style_var_when_type_is_apparent = false
+
+# Члены, заданные выражениями
+csharp_style_expression_bodied_accessors = true
+csharp_style_expression_bodied_constructors = false
+csharp_style_expression_bodied_indexers = true
+csharp_style_expression_bodied_lambdas = true
+csharp_style_expression_bodied_local_functions = false
+csharp_style_expression_bodied_methods = false
+csharp_style_expression_bodied_operators = false
+csharp_style_expression_bodied_properties = true
+
+# Настройки соответствия шаблонов
+csharp_style_pattern_matching_over_as_with_null_check = true
+csharp_style_pattern_matching_over_is_with_cast_check = true
+csharp_style_prefer_extended_property_pattern = true
+csharp_style_prefer_not_pattern = true
+csharp_style_prefer_pattern_matching = true
+csharp_style_prefer_switch_expression = true
+
+# Настройки проверки на null
+csharp_style_conditional_delegate_call = true
+
+# Предпочтения модификатора
+csharp_prefer_static_anonymous_function = true
+csharp_prefer_static_local_function = true
+csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
+csharp_style_prefer_readonly_struct = true
+csharp_style_prefer_readonly_struct_member = true
+
+# Предпочтения для блоков кода
+csharp_prefer_braces = true
+csharp_prefer_simple_using_statement = true
+csharp_prefer_system_threading_lock = true
+csharp_style_namespace_declarations = file_scoped
+csharp_style_prefer_method_group_conversion = true
+csharp_style_prefer_primary_constructors = true
+csharp_style_prefer_top_level_statements = true
+
+# Выражения уровень предпочтения
+csharp_prefer_simple_default_expression = true:suggestion
+csharp_style_deconstructed_variable_declaration = true:suggestion
+csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+csharp_style_prefer_index_operator = true:suggestion
+csharp_style_prefer_local_over_anonymous_function = true:suggestion
+csharp_style_prefer_null_check_over_type_check = true:suggestion
+csharp_style_prefer_range_operator = true:suggestion
+csharp_style_prefer_tuple_swap = true:suggestion
+csharp_style_prefer_unbound_generic_type_in_nameof = true:suggestion
+csharp_style_prefer_utf8_string_literals = true:suggestion
+csharp_style_throw_expression = true:suggestion
+csharp_style_unused_value_assignment_preference = discard_variable:suggestion
+csharp_style_unused_value_expression_statement_preference = discard_variable:silent
+
+# предпочтения для директивы using
+csharp_using_directive_placement = outside_namespace
+
+# Предпочтения для новых строк
+csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
+csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true
+csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true
+csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
+csharp_style_allow_embedded_statements_on_same_line_experimental = true
+
+#### Правила форматирования C# ####
+
+# Предпочтения для новых строк
+csharp_new_line_before_catch = true
+csharp_new_line_before_else = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_open_brace = all
+csharp_new_line_between_query_expression_clauses = true
+
+# Параметры отступов
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_case_contents_when_block = false
+csharp_indent_labels = one_less_than_current
+csharp_indent_switch_labels = true
+
+# Предпочтения для интервалов
+csharp_space_after_cast = true
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+
+# Параметры переноса
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = false
+
+#### Стили именования ####
+
+# Правила именования
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Спецификации символов
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+# Стили именования
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+[*.{cs,vb}]
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+dotnet_style_prefer_auto_properties = true:silent
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
+dotnet_style_prefer_conditional_expression_over_assignment = true:silent
+dotnet_style_prefer_conditional_expression_over_return = true:silent
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
+dotnet_style_prefer_compound_assignment = true:suggestion
+dotnet_style_prefer_simplified_interpolation = true:suggestion
+dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion
+dotnet_style_namespace_match_folder = true:suggestion
+dotnet_code_quality_unused_parameters = all:suggestion
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+tab_width = 4
+indent_size = 4
\ No newline at end of file
diff --git a/Pf2eDataScrapper/EnvSettings.cs b/Pf2eDataScrapper/EnvSettings.cs
index 5a5fffb..dd1b457 100644
--- a/Pf2eDataScrapper/EnvSettings.cs
+++ b/Pf2eDataScrapper/EnvSettings.cs
@@ -1,41 +1,40 @@
using dotenv.net;
using dotenv.net.Utilities;
-namespace Pf2eDataScrapper
+namespace Pf2eDataScrapper;
+
+///
+/// Класс настроек.
+///
+internal static class EnvSettings
{
///
- /// Класс настроек.
+ /// Загрузка файла настроек `.env`.
///
- internal static class EnvSettings
+ public static void Load()
{
- ///
- /// Загрузка файла настроек `.env`.
- ///
- public static void Load()
- {
- DotEnv.Load();
- }
-
- ///
- /// Путь к папке с входными данными.
- ///
- public static string DataDirPath => EnvReader.GetStringValue("DATA_DIR");
-
- ///
- /// Папка в входными данными.
- ///
- public static DirectoryInfo DataDir => new(DataDirPath);
-
- ///
- /// Путь к папке для сохранения результатов.
- ///
- public static string OutputDirPath => EnvReader.GetStringValue("OUTPUT_DIR");
-
- ///
- /// Папка для сохранения результатов.
- ///
- public static string OutputDir => new(OutputDirPath);
-
- public static string DatabaseConnection => EnvReader.GetStringValue("DATABASE_CONNECTION");
+ DotEnv.Load();
}
+
+ ///
+ /// Путь к папке с входными данными.
+ ///
+ public static string DataDirPath => EnvReader.GetStringValue("DATA_DIR");
+
+ ///
+ /// Папка в входными данными.
+ ///
+ public static DirectoryInfo DataDir => new(DataDirPath);
+
+ ///
+ /// Путь к папке для сохранения результатов.
+ ///
+ public static string OutputDirPath => EnvReader.GetStringValue("OUTPUT_DIR");
+
+ ///
+ /// Папка для сохранения результатов.
+ ///
+ public static string OutputDir => new(OutputDirPath);
+
+ public static string DatabaseConnection => EnvReader.GetStringValue("DATABASE_CONNECTION");
}
diff --git a/Pf2eDataScrapper/Importers/AbstractImporter.cs b/Pf2eDataScrapper/Importers/AbstractImporter.cs
index 1076b91..f1f93ac 100644
--- a/Pf2eDataScrapper/Importers/AbstractImporter.cs
+++ b/Pf2eDataScrapper/Importers/AbstractImporter.cs
@@ -1,42 +1,41 @@
using Pf2eDataScrapper.Importers.Repositories;
-namespace Pf2eDataScrapper.Importers
+namespace Pf2eDataScrapper.Importers;
+
+///
+/// Абстрактный класс импортёра
+///
+internal abstract class AbstractImporter
{
///
- /// Абстрактный класс импортёра
+ /// Отображаемое имя импортёра
///
- internal abstract class AbstractImporter
- {
- ///
- /// Отображаемое имя импортёра
- ///
- public abstract string Name { get; }
+ public abstract string Name { get; }
- ///
- /// Короткое имя импортёра
- ///
- public abstract string Slug { get; }
+ ///
+ /// Короткое имя импортёра
+ ///
+ public abstract string Slug { get; }
- public abstract AbstractImporterRepository Repository { get; }
+ public abstract AbstractImporterRepository Repository { get; }
- ///
- /// Путь к директории с данными для импортёра
- ///
- public string Dir => Path.Combine(EnvSettings.DataDirPath, Slug);
+ ///
+ /// Путь к директории с данными для импортёра
+ ///
+ public string Dir => Path.Combine(EnvSettings.DataDirPath, Slug);
- ///
- /// Метод подготовки данных для импорта
- ///
- public abstract void Prepare();
+ ///
+ /// Метод подготовки данных для импорта
+ ///
+ public abstract void Prepare();
- ///
- /// Импорт данных
- ///
- public abstract void Import();
+ ///
+ /// Импорт данных
+ ///
+ public abstract void Import();
- ///
- /// Построение схем данных
- ///
- public abstract void BuildSchemas();
- }
+ ///
+ /// Построение схем данных
+ ///
+ public abstract void BuildSchemas();
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/AonprdImporter.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/AonprdImporter.cs
index ede516a..425274d 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/AonprdImporter.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/AonprdImporter.cs
@@ -1,40 +1,39 @@
-using Pf2eDataScrapper.Importers.Repositories;
-using Pf2eDataScrapper.Importers.Implementations.Aonprd.SchemaBuilder;
+using Pf2eDataScrapper.Importers.Implementations.Aonprd.SchemaBuilder;
+using Pf2eDataScrapper.Importers.Repositories;
-namespace Pf2eDataScrapper.Importers.Implementations.Aonprd
+namespace Pf2eDataScrapper.Importers.Implementations.Aonprd;
+
+internal class AonprdImporter : AbstractImporter
{
- internal class AonprdImporter : AbstractImporter
+ public override string Name => "Archives of Nethys Pathfinder 2e";
+
+ public override string Slug => "aonprd";
+
+ public override AbstractImporterRepository Repository => new AonprdRepository(this, "https://elasticsearch.aonprd.com");
+
+ public AonprdLoader Loader { get; }
+
+ public AonprdImporter()
{
- public override string Name => "Archives of Nethys Pathfinder 2e";
+ Loader = new AonprdLoader(this);
+ }
- public override string Slug => "aonprd";
+ public override void Prepare()
+ {
+ Repository.Update();
+ Loader.Prepare();
+ }
- public override AbstractImporterRepository Repository => new AonprdRepository(this, "https://elasticsearch.aonprd.com");
+ public override void BuildSchemas()
+ {
+ AonprdSchemaBuilder builder = new(Loader);
- public AonprdLoader Loader { get; }
+ builder.BuildSchemas();
+ builder.Save(EnvSettings.OutputDir);
+ }
- public AonprdImporter()
- {
- Loader = new AonprdLoader(this);
- }
-
- public override void Prepare()
- {
- Repository.Update();
- Loader.Prepare();
- }
-
- public override void BuildSchemas()
- {
- var builder = new AonprdSchemaBuilder(Loader);
-
- builder.BuildSchemas();
- builder.Save(EnvSettings.OutputDir);
- }
-
- public override void Import()
- {
- throw new NotImplementedException();
- }
+ public override void Import()
+ {
+ throw new NotImplementedException();
}
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/AonprdLoader.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/AonprdLoader.cs
index c5baa85..ba0fc32 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/AonprdLoader.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/AonprdLoader.cs
@@ -1,79 +1,77 @@
-using Microsoft.EntityFrameworkCore.Metadata.Internal;
-using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium;
-namespace Pf2eDataScrapper.Importers.Implementations.Aonprd
+namespace Pf2eDataScrapper.Importers.Implementations.Aonprd;
+
+internal class AonprdLoader(AonprdImporter importer)
{
- internal class AonprdLoader (AonprdImporter importer)
+ public AonprdImporter Importer = importer;
+
+ public AonprdCompendium Compendium = new();
+
+ public int ItemCount => Compendium.Count;
+
+ public void Prepare()
{
- public AonprdImporter Importer = importer;
+ using StreamReader indexFile = new(Path.Combine(Importer.Dir, "index.json"));
+ JObject indexJson = JObject.Parse(indexFile.ReadToEnd());
- public AonprdCompendium Compendium = new();
-
- public int ItemCount => Compendium.Count;
-
- public void Prepare()
+ foreach (KeyValuePair kvp in indexJson)
{
- using var indexFile = new StreamReader(Path.Combine(Importer.Dir, "index.json"));
- var indexJson = JObject.Parse(indexFile.ReadToEnd());
+ string file = kvp.Key.ToString();
+ JArray items = (JArray) kvp.Value!;
- foreach (var kvp in indexJson)
+ foreach (JToken item in items)
{
- var file = kvp.Key.ToString();
- var items = (JArray)kvp.Value!;
-
- foreach (var item in items)
- {
- Compendium.AddReference(item.ToString(), file);
- }
+ Compendium.AddReference(item.ToString(), file);
}
}
+ }
- public IEnumerable Entries()
- {
- return Entries(Compendium.Types.Keys.ToArray());
- }
+ public IEnumerable Entries()
+ {
+ return Entries([.. Compendium.Types.Keys]);
+ }
- public IEnumerable Entries(string types)
- {
- return Entries([types]);
- }
+ public IEnumerable Entries(string types)
+ {
+ return Entries([types]);
+ }
- public IEnumerable Entries(string[] types)
+ public IEnumerable Entries(string[] types)
+ {
+ foreach (string? file in Compendium.Files(types))
{
- foreach (var file in Compendium.Files(types))
+ if (file is null)
{
- if (file is null)
+ continue;
+ }
+
+ using StreamReader fileReader = new(Path.Combine(Importer.Dir, $"{file}.json"));
+ JArray array = JArray.Parse(fileReader.ReadToEnd());
+
+ foreach (JToken item in array)
+ {
+ string? id = item.SelectToken("id")?.ToString();
+
+ if (id is null)
{
continue;
}
- using var fileReader = new StreamReader(Path.Combine(Importer.Dir, $"{file}.json"));
- var array = JArray.Parse(fileReader.ReadToEnd());
+ LoaderEntry entry = new(id, file, (JObject) item);
- foreach (var item in array)
+ if (types.Contains(entry.Type))
{
- var id = item.SelectToken("id")?.ToString();
-
- if (id is null)
- {
- continue;
- }
-
- var entry = new LoaderEntry(id, file, (JObject)item);
-
- if (types.Contains(entry.Type))
- {
- yield return entry;
- }
+ yield return entry;
}
}
}
+ }
- public class LoaderEntry(string id, string file, JObject itemJson) : AonprdReference(id, file)
- {
- public JObject Json { get; } = itemJson;
- }
+ public class LoaderEntry(string id, string file, JObject itemJson) : AonprdReference(id, file)
+ {
+ public JObject Json { get; } = itemJson;
}
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/AonprdRepository.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/AonprdRepository.cs
index 1d4cc34..112df9a 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/AonprdRepository.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/AonprdRepository.cs
@@ -2,101 +2,100 @@
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.Importers.Repositories;
-namespace Pf2eDataScrapper.Importers.Implementations.Aonprd
+namespace Pf2eDataScrapper.Importers.Implementations.Aonprd;
+
+internal class AonprdRepository(AbstractImporter importer, string searchUrl) : AbstractImporterRepository(importer)
{
- internal class AonprdRepository(AbstractImporter importer, string searchUrl): AbstractImporterRepository(importer)
+ public readonly string SearchUrl = searchUrl;
+
+ public int Revision { get; private set; }
+
+ private string Load(string url)
{
- public readonly string SearchUrl = searchUrl;
-
- public int Revision { get; private set; }
-
- private string Load(string url)
+ if (!url.StartsWith("http://") && !url.StartsWith("https://"))
{
- if (!url.StartsWith("http://") && !url.StartsWith("https://"))
- {
- url = SearchUrl + url;
- }
+ url = SearchUrl + url;
+ }
- using var client = new HttpClient();
- using var stream = client.GetStreamAsync(url);
- using var reader = new StreamReader(stream.Result);
+ using HttpClient client = new();
+ using Task stream = client.GetStreamAsync(url);
+ using StreamReader reader = new(stream.Result);
- return reader.ReadToEnd();
+ return reader.ReadToEnd();
+ }
+
+
+ public override void Update()
+ {
+ if (CheckRevision())
+ {
+ Console.WriteLine($"Данные Aonprd актуальны, текущая ревизия {Revision}.");
+ return;
+ }
+
+ Console.WriteLine($"Данные Aonprd устарели, обновляем {RepositoryDirPath} до ревизии {Revision}...");
+
+ if (Directory.Exists(RepositoryDirPath))
+ {
+ Directory.Delete(RepositoryDirPath, true);
+ }
+ Directory.CreateDirectory(RepositoryDirPath);
+
+ WriteFile("revision.txt", Revision.ToString());
+
+ Console.WriteLine("Загрузка индекса...");
+ string indexContent = Load($"/json-data/aon{Revision}-index.json");
+ WriteFile("index.json", indexContent);
+
+ JObject indexJson = JObject.Parse(indexContent);
+
+ Console.WriteLine("Загрузка индексных файлов...");
+
+ ProgressBar bar = new(indexJson.Count);
+ int i = 0;
+
+ foreach (KeyValuePair kvp in indexJson)
+ {
+ string fileName = kvp.Key;
+ bar.Refresh(i++, fileName);
+
+ string fileContent = Load($"/json-data/{fileName}.json");
+ WriteFile($"{fileName}.json", fileContent);
}
- public override void Update()
+ bar.Refresh(indexJson.Count, "Готово!");
+ }
+
+ ///
+ /// Проверка актуальности данных
+ ///
+ /// true - актуальная ревизия, false - устаревшая/отсутсвует
+ private bool CheckRevision()
+ {
+ JObject page = JObject.Parse(Load("/aon/_doc/feat-1"));
+
+ Revision = Convert.ToInt32(page.SelectToken("_index")?.ToObject()?.Replace("aon", "") ?? throw new Exception("Can't get revision"));
+
+ string revisionFile = Path.Combine(RepositoryDirPath, "revision.txt");
+ if (!File.Exists(revisionFile))
{
- if (CheckRevision())
- {
- Console.WriteLine($"Данные Aonprd актуальны, текущая ревизия {Revision}.");
- return;
- }
-
- Console.WriteLine($"Данные Aonprd устарели, обновляем {RepositoryDirPath} до ревизии {Revision}...");
-
- if (Directory.Exists(RepositoryDirPath))
- {
- Directory.Delete(RepositoryDirPath, true);
- }
- Directory.CreateDirectory(RepositoryDirPath);
-
- WriteFile("revision.txt", Revision.ToString());
-
- Console.WriteLine("Загрузка индекса...");
- var indexContent = Load($"/json-data/aon{Revision}-index.json");
- WriteFile("index.json", indexContent);
-
- var indexJson = JObject.Parse(indexContent);
-
- Console.WriteLine("Загрузка индексных файлов...");
-
- var bar = new ProgressBar(indexJson.Count);
- var i = 0;
-
- foreach (var kvp in indexJson)
- {
- var fileName = kvp.Key;
- bar.Refresh(i++, fileName);
-
- var fileContent = Load($"/json-data/{fileName}.json");
- WriteFile($"{fileName}.json", fileContent);
- }
-
-
- bar.Refresh(indexJson.Count, "Готово!");
+ return false;
}
- ///
- /// Проверка актуальности данных
- ///
- /// true - актуальная ревизия, false - устаревшая/отсутсвует
- private bool CheckRevision()
+ using StreamReader reader = new(revisionFile);
+ string lastRevision = reader.ReadToEnd();
+ return lastRevision == Revision.ToString();
+ }
+
+ private void WriteFile(string path, string content)
+ {
+ string filePath = Path.Combine(RepositoryDirPath, path);
+ if (File.Exists(filePath))
{
- var page = JObject.Parse(Load("/aon/_doc/feat-1"));
-
- Revision = Convert.ToInt32(page.SelectToken("_index")?.ToObject()?.Replace("aon", "") ?? throw new Exception("Can't get revision"));
-
- var revisionFile = Path.Combine(RepositoryDirPath, "revision.txt");
- if (!File.Exists(revisionFile))
- {
- return false;
- }
-
- using var reader = new StreamReader(revisionFile);
- var lastRevision = reader.ReadToEnd();
- return lastRevision == Revision.ToString();
- }
-
- private void WriteFile (string path, string content)
- {
- var filePath = Path.Combine(RepositoryDirPath, path);
- if (File.Exists(filePath))
- {
- File.Delete(filePath);
- }
- using var writer = new StreamWriter(filePath);
- writer.Write(content);
+ File.Delete(filePath);
}
+ using StreamWriter writer = new(filePath);
+ writer.Write(content);
}
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Compendium/AonprdCompendium.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Compendium/AonprdCompendium.cs
index 761cac2..02b2463 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Compendium/AonprdCompendium.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Compendium/AonprdCompendium.cs
@@ -1,28 +1,27 @@
-namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium
+namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium;
+
+internal class AonprdCompendium
{
- internal class AonprdCompendium
+ public readonly Dictionary Types = [];
+
+ public void AddReference(string id, string file)
{
- public readonly Dictionary Types = [];
+ AonprdReference reference = new(id, file);
- public void AddReference(string id, string file)
+ if (Types.TryGetValue(reference.Type, out AonprdType? type))
{
- AonprdReference reference = new(id, file);
-
- if (Types.TryGetValue(reference.Type, out var type))
- {
- type.Add(reference);
- }
- else
- {
- Types.Add(reference.Type, new AonprdType(reference));
- }
+ type.Add(reference);
+ }
+ else
+ {
+ Types.Add(reference.Type, new AonprdType(reference));
}
-
- public int Count => Types.Values.Sum(x => x.Count);
-
- public IEnumerable Files(IEnumerable types) => Types.Values
- .Where(t => types.Contains(t.Type))
- .SelectMany(t => t.Files)
- .Distinct();
}
+
+ public int Count => Types.Values.Sum(x => x.Count);
+
+ public IEnumerable Files(IEnumerable types) => Types.Values
+ .Where(t => types.Contains(t.Type))
+ .SelectMany(t => t.Files)
+ .Distinct();
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Compendium/AonprdReference.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Compendium/AonprdReference.cs
index 384d066..a54b95b 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Compendium/AonprdReference.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Compendium/AonprdReference.cs
@@ -1,35 +1,23 @@
-namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium
+namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium;
+
+internal class AonprdReference(string id, string file)
{
- internal class AonprdReference(string id, string file)
+ public readonly string Id = id;
+
+ public readonly string Type = ResolveType(id);
+
+ public readonly string File = file;
+
+ public static string ResolveType(string id)
{
- public readonly string Id = id;
-
- public readonly string Type = ResolveType(id);
-
- public readonly string File = file;
-
- public static string ResolveType(string id)
+ static string? subType(string type, string cat)
{
- static string? subType(string type, string cat)
- {
- if (type.StartsWith($"{cat}-") && type != cat)
- {
- if (type.EndsWith("-bonus"))
- {
- return $"{cat}-bonus";
- }
- else
- {
- return $"{cat}-sub";
- }
- }
- return null;
- }
-
- var type = string.Join('-', id.Split('-')[0..^1]);
-
- return subType(type, "equipment") ?? subType(type, "weapon") ?? type;
+ return type.StartsWith($"{cat}-") && type != cat ? type.EndsWith("-bonus") ? $"{cat}-bonus" : $"{cat}-sub" : null;
}
+
+ string type = string.Join('-', id.Split('-')[0..^1]);
+
+ return subType(type, "equipment") ?? subType(type, "weapon") ?? type;
}
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Compendium/AonprdType.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Compendium/AonprdType.cs
index 8212a36..5a52fb9 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Compendium/AonprdType.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Compendium/AonprdType.cs
@@ -1,23 +1,22 @@
-namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium
+namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium;
+
+internal class AonprdType(string type)
{
- internal class AonprdType(string type)
+ public readonly string Type = type;
+
+ public readonly List Items = [];
+
+ public AonprdType(AonprdReference reference) : this(reference.Type)
{
- public readonly string Type = type;
-
- public readonly List Items = [];
-
- public AonprdType(AonprdReference reference) : this(reference.Type)
- {
- Items.Add(reference);
- }
-
- public void Add(AonprdReference reference)
- {
- Items.Add(reference);
- }
-
- public List Files => [.. Items.Select(x => x.File).Distinct()];
-
- public int Count => Items.Count;
+ Items.Add(reference);
}
+
+ public void Add(AonprdReference reference)
+ {
+ Items.Add(reference);
+ }
+
+ public List Files => [.. Items.Select(x => x.File).Distinct()];
+
+ public int Count => Items.Count;
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/SchemaBuilder/AonprdSchemaBuilder.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/SchemaBuilder/AonprdSchemaBuilder.cs
index 284132d..f06a888 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/SchemaBuilder/AonprdSchemaBuilder.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/SchemaBuilder/AonprdSchemaBuilder.cs
@@ -2,86 +2,85 @@
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium;
using Pf2eDataScrapper.SchemaBuilder;
-namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.SchemaBuilder
+namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.SchemaBuilder;
+
+internal class AonprdSchemaBuilder(AonprdLoader loader)
{
- internal class AonprdSchemaBuilder(AonprdLoader loader)
+ public readonly AonprdLoader Loader = loader;
+
+ public readonly AonprdCompendium Compendium = loader.Compendium;
+
+ // public readonly AonprdSchemaTypeResolver Resolver = new();
+
+ public readonly Dictionary Schemas = [];
+
+ private SchemaNode GetSchema(AonprdLoader.LoaderEntry entry)
{
- public readonly AonprdLoader Loader = loader;
-
- public readonly AonprdCompendium Compendium = loader.Compendium;
-
- // public readonly AonprdSchemaTypeResolver Resolver = new();
-
- public readonly Dictionary Schemas = [];
-
- private SchemaNode GetSchema(AonprdLoader.LoaderEntry entry)
+ string key = entry.Type;
+ if (!Schemas.TryGetValue(key, out SchemaNode? value))
{
- string key = entry.Type;
- if (!Schemas.TryGetValue(key, out SchemaNode? value))
+ value = new SchemaNode()
{
- value = new SchemaNode()
- {
- // Resolver = Resolver,
- Path = key
- };
- Schemas[key] = value;
- }
- return value;
+ // Resolver = Resolver,
+ Path = key
+ };
+ Schemas[key] = value;
+ }
+ return value;
+ }
+
+ public void BuildSchemas()
+ {
+ Console.WriteLine("Building schemas...");
+
+ ProgressBar bar = new ProgressBar(Loader.ItemCount);
+ int i = 0;
+
+ foreach (AonprdLoader.LoaderEntry entry in Loader.Entries())
+ {
+ bar.Refresh(i++, entry.Type);
+ GetSchema(entry).AddValue(entry.Json);
}
- public void BuildSchemas()
+ bar.Refresh(Loader.ItemCount, "Done!");
+ }
+
+ public void Save(string targetDir)
+ {
+ Console.WriteLine("Dumping schemas...");
+
+ targetDir = Path.Combine(targetDir, Loader.Importer.Slug);
+
+ ProgressBar bar = new(Schemas.Count);
+ int i = 0;
+
+ foreach (KeyValuePair kvp in Schemas)
{
- Console.WriteLine("Building schemas...");
-
- var bar = new ProgressBar(Loader.ItemCount);
- var i = 0;
-
- foreach (var entry in Loader.Entries())
- {
- bar.Refresh(i++, entry.Type);
- GetSchema(entry).AddValue(entry.Json);
- }
-
- bar.Refresh(Loader.ItemCount, "Done!");
- }
-
- public void Save(string targetDir)
- {
- Console.WriteLine("Dumping schemas...");
-
- targetDir = Path.Combine(targetDir, Loader.Importer.Slug);
-
- var bar = new ProgressBar(Schemas.Count);
- var i = 0;
-
- foreach (var kvp in Schemas)
- {
- bar.Refresh(i++, kvp.Key);
- SaveSchema(targetDir, kvp.Key, kvp.Value);
- }
- }
-
- protected void SaveSchema(string dir, string name, SchemaNode schema)
- {
- var invalids = Path.GetInvalidFileNameChars();
- var fileName = string.Join("_", schema.Path.Split(invalids, StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.');
- var path = Path.Combine(dir, fileName + ".yaml");
-
- var dirPath = Path.GetDirectoryName(path);
- if (dirPath is not null && !Directory.Exists(dirPath))
- {
- Directory.CreateDirectory(dirPath);
- }
-
- using var writer = new StreamWriter(path);
-
- schema.Beautify();
-
- writer.WriteLine(SchemaNode.FormatYaml(new Dictionary()
- {
- ["name"] = name,
- ["values"] = schema.Values.ToString()
- }, schema.Types[0].GetYamlData()));
+ bar.Refresh(i++, kvp.Key);
+ SaveSchema(targetDir, kvp.Key, kvp.Value);
}
}
+
+ protected void SaveSchema(string dir, string name, SchemaNode schema)
+ {
+ char[] invalids = Path.GetInvalidFileNameChars();
+ string fileName = string.Join("_", schema.Path.Split(invalids, StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.');
+ string path = Path.Combine(dir, fileName + ".yaml");
+
+ string? dirPath = Path.GetDirectoryName(path);
+ if (dirPath is not null && !Directory.Exists(dirPath))
+ {
+ Directory.CreateDirectory(dirPath);
+ }
+
+ using StreamWriter writer = new(path);
+
+ schema.Beautify();
+
+ writer.WriteLine(SchemaNode.FormatYaml(new Dictionary()
+ {
+ ["name"] = name,
+ ["values"] = schema.Values.ToString()
+ }, schema.Types[0].GetYamlData()));
+ }
}
\ No newline at end of file
diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumDocumentType.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumDocumentType.cs
index ce2b9f5..3c2e48a 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumDocumentType.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumDocumentType.cs
@@ -1,18 +1,17 @@
-namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
+namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium;
+
+///
+/// Тип документов компендиума.
+///
+internal enum CompendiumDocumentType
{
- ///
- /// Тип документов компендиума.
- ///
- internal enum CompendiumDocumentType
- {
- Actor,
- Adventure,
- Cards,
- Item,
- JournalEntry,
- Macro,
- Playlist,
- RollTable,
- Scene
- }
+ Actor,
+ Adventure,
+ Cards,
+ Item,
+ JournalEntry,
+ Macro,
+ Playlist,
+ RollTable,
+ Scene
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolder.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolder.cs
index 41b1b6b..9a6bd91 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolder.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolder.cs
@@ -1,88 +1,87 @@
using Newtonsoft.Json.Linq;
-namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
+namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium;
+
+///
+/// Папка компендиума.
+///
+internal class CompendiumFolder
{
///
- /// Папка компендиума.
+ /// Идентификатор папки.
///
- internal class CompendiumFolder
+ public readonly string Id;
+
+ ///
+ /// Название папки.
+ ///
+ public readonly string Name;
+
+ ///
+ /// Путь к папке.
+ ///
+ public readonly string? Path;
+
+ ///
+ /// Указатель, что папка содержится в других папках.
+ ///
+ public readonly bool IsContained;
+
+ ///
+ /// Родительская папка.
+ ///
+ public CompendiumFolder? Parent;
+
+ ///
+ /// Тип документов в папке.
+ ///
+ public readonly CompendiumDocumentType Type;
+
+ ///
+ /// Конструктор папки компендиума из JSON-объекта.
+ ///
+ ///
+ public CompendiumFolder(JObject json)
{
- ///
- /// Идентификатор папки.
- ///
- public readonly string Id;
-
- ///
- /// Название папки.
- ///
- public readonly string Name;
-
- ///
- /// Путь к папке.
- ///
- public readonly string? Path;
-
- ///
- /// Указатель, что папка содержится в других папках.
- ///
- public readonly bool IsContained;
-
- ///
- /// Родительская папка.
- ///
- public CompendiumFolder? Parent;
-
- ///
- /// Тип документов в папке.
- ///
- public readonly CompendiumDocumentType Type;
-
- ///
- /// Конструктор папки компендиума из JSON-объекта.
- ///
- ///
- public CompendiumFolder(JObject json)
+ if (json.TryGetValue("_id", out JToken? id))
{
- if (json.TryGetValue("_id", out var id))
- {
- // Вложенная папка через _folders.json
- Id = id!.ToString();
- Name = json["name"]!.ToString();
- Path = null;
- IsContained = true;
- }
- else
- {
- // Корневой пак в system.json
- Id = json["name"]!.ToString();
- Name = json["label"]!.ToString();
- Path = json["path"]!.ToString();
- IsContained = false;
- }
-
- Type = (CompendiumDocumentType)Enum.Parse(typeof(CompendiumDocumentType), json["type"]!.ToString());
- }
-
- ///
- /// Конструктор папки компендиума.
- ///
- /// Идентификатор папки.
- /// Название папки.
- public CompendiumFolder(string id, string name)
- {
- Id = id;
- Name = name;
+ // Вложенная папка через _folders.json
+ Id = id!.ToString();
+ Name = json["name"]!.ToString();
Path = null;
+ IsContained = true;
+ }
+ else
+ {
+ // Корневой пак в system.json
+ Id = json["name"]!.ToString();
+ Name = json["label"]!.ToString();
+ Path = json["path"]!.ToString();
IsContained = false;
}
- ///
- /// Строковое представление данных о папки компендиума.
- ///
- /// Строковое представление данных о папки компендиума.
- public override string ToString()
- {
- return $"CompendiumFolder([Id={Id}][Type={Type}][Name={Name}][Path={Path}][Parent={Parent?.Name ?? "null"}])";
- }
+ Type = (CompendiumDocumentType) Enum.Parse(typeof(CompendiumDocumentType), json["type"]!.ToString());
+ }
+
+ ///
+ /// Конструктор папки компендиума.
+ ///
+ /// Идентификатор папки.
+ /// Название папки.
+ public CompendiumFolder(string id, string name)
+ {
+ Id = id;
+ Name = name;
+ Path = null;
+ IsContained = false;
+ }
+
+ ///
+ /// Строковое представление данных о папки компендиума.
+ ///
+ /// Строковое представление данных о папки компендиума.
+ public override string ToString()
+ {
+ return $"CompendiumFolder([Id={Id}][Type={Type}][Name={Name}][Path={Path}][Parent={Parent?.Name ?? "null"}])";
}
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolderCollection.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolderCollection.cs
index 4067ca1..532c5e3 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolderCollection.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolderCollection.cs
@@ -1,28 +1,27 @@
-namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
+namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium;
+
+///
+/// Коллекция папок компендиума
+///
+internal class CompendiumFolderCollection : List
{
///
- /// Коллекция папок компендиума
+ /// Получение папки по идентификатору
///
- internal class CompendiumFolderCollection : List
+ /// Искомый идентификатор
+ /// Искомая папка
+ public CompendiumFolder? GetById(string id)
{
- ///
- /// Получение папки по идентификатору
- ///
- /// Искомый идентификатор
- /// Искомая папка
- public CompendiumFolder? GetById(string id)
- {
- return this.FirstOrDefault(x => x.Id == id);
- }
+ return this.FirstOrDefault(x => x.Id == id);
+ }
- ///
- /// Фильтрация требуемых папок компендиума.
- ///
- ///
- public CompendiumFolderCollection Filter()
- {
- // return [.. this.FindAll(x => x.Type != CompendiumDocumentType.Actor)];
- return [.. this.FindAll(x => x.Type != CompendiumDocumentType.Actor && x.Name == "Conditions")];
- }
+ ///
+ /// Фильтрация требуемых папок компендиума.
+ ///
+ ///
+ public CompendiumFolderCollection Filter()
+ {
+ // return [.. this.FindAll(x => x.Type != CompendiumDocumentType.Actor)];
+ return [.. this.FindAll(x => x.Type != CompendiumDocumentType.Actor && x.Name == "Conditions")];
}
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/CompendiumLoader.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/CompendiumLoader.cs
index c039983..1c7d645 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/CompendiumLoader.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/CompendiumLoader.cs
@@ -1,170 +1,169 @@
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium;
-namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry
+namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry;
+
+///
+/// Загрузчик данных компендиума
+///
+/// Импортёр
+internal class CompendiumLoader(Pf2EFoundryImporter importer)
{
///
- /// Загрузчик данных компендиума
+ /// Импортёр
///
- /// Импортёр
- internal class CompendiumLoader(Pf2EFoundryImporter importer)
+ public readonly Pf2EFoundryImporter Importer = importer;
+
+ ///
+ /// Набор папок компендиума
+ ///
+ public CompendiumFolderCollection Collection = [];
+
+ ///
+ /// Счётчик папок
+ ///
+ private int _folderCount = 0;
+
+ ///
+ /// Общее количество элементов в компендиуме
+ ///
+ public int ItemCount { get; protected set; } = 0;
+
+ ///
+ /// Обработка папок компендиума в поле `packFolders`.
+ ///
+ ///
+ ///
+ protected void ProcessPackFolders(JArray folders, CompendiumFolder? parent)
{
- ///
- /// Импортёр
- ///
- public readonly Pf2EFoundryImporter Importer = importer;
-
- ///
- /// Набор папок компендиума
- ///
- public CompendiumFolderCollection Collection = [];
-
- ///
- /// Счётчик папок
- ///
- private int _folderCount = 0;
-
- ///
- /// Общее количество элементов в компендиуме
- ///
- public int ItemCount { get; protected set; } = 0;
-
- ///
- /// Обработка папок компендиума в поле `packFolders`.
- ///
- ///
- ///
- protected void ProcessPackFolders(JArray folders, CompendiumFolder? parent)
+ foreach (JToken token in folders)
{
- foreach (var token in folders)
+ JObject obj = (JObject) token;
+
+ string id = $"folder-{_folderCount++}";
+ string name = obj["name"]!.ToString();
+
+ CompendiumFolder folder = new(id, name)
{
- JObject obj = (JObject)token;
+ Parent = parent
+ };
+ Collection.Add(folder);
- var id = $"folder-{_folderCount++}";
- var name = obj["name"]!.ToString();
-
- var folder = new CompendiumFolder(id, name)
+ if (obj.TryGetValue("packs", out JToken? packs))
+ {
+ foreach (JToken jToken in packs!)
{
- Parent = parent
- };
- Collection.Add(folder);
+ string packId = jToken.ToString();
+ CompendiumFolder? child = Collection.GetById(packId);
- if (obj.TryGetValue("packs", out var packs))
- {
- foreach (var jToken in packs!)
+ if (child is not null)
{
- var packId = jToken.ToString();
- var child = Collection.GetById(packId);
-
- if (child is not null)
- {
- child.Parent = folder;
- }
+ child.Parent = folder;
}
}
-
- if (obj.TryGetValue("folders", out var innerFolders))
- {
- ProcessPackFolders((JArray)innerFolders!, folder);
- }
}
- Collection = Collection.Filter();
+ if (obj.TryGetValue("folders", out JToken? innerFolders))
+ {
+ ProcessPackFolders((JArray) innerFolders!, folder);
+ }
}
- ///
- /// Подготовка набора папок компендиума
- ///
- public void Prepare()
+ Collection = Collection.Filter();
+ }
+
+ ///
+ /// Подготовка набора папок компендиума
+ ///
+ public void Prepare()
+ {
+ using StreamReader systemFile = new(Path.Combine(Importer.Dir, "static", "system.json"));
+ JObject systemData = JObject.Parse(systemFile.ReadToEnd());
+
+ foreach (JToken pack in systemData["packs"]!)
{
- using var systemFile = new StreamReader(Path.Combine(Importer.Dir, "static", "system.json"));
- var systemData = JObject.Parse(systemFile.ReadToEnd());
+ CompendiumFolder folder = new((JObject) pack);
- foreach (var pack in systemData["packs"]!)
+ Collection.Add(folder);
+ }
+
+ if (systemData.TryGetValue("packFolders", out JToken? packFolders))
+ {
+ ProcessPackFolders((JArray) packFolders, null);
+ }
+
+ // Поиск _folders.json
+ foreach (CompendiumFolder? parent in Collection.ToList())
+ {
+ if (parent.Path is null)
{
- var folder = new CompendiumFolder((JObject)pack);
-
- Collection.Add(folder);
+ continue;
}
- if (systemData.TryGetValue("packFolders", out var packFolders))
- {
- ProcessPackFolders((JArray)packFolders, null);
- }
+ string dirPath = Path.Combine(Importer.Dir, parent.Path);
- // Поиск _folders.json
- foreach (var parent in Collection.ToList())
+ ItemCount += Directory.GetFiles(dirPath, "*.json", SearchOption.AllDirectories)
+ .Length;
+
+ foreach (string foldersFilePath in Directory.GetFiles(dirPath, "_folders.json", SearchOption.AllDirectories))
{
- if (parent.Path is null)
+ ItemCount--;
+ using StreamReader file = new(foldersFilePath);
+ JArray data = JArray.Parse(file.ReadToEnd());
+
+ foreach (JToken pack in data)
+ {
+ CompendiumFolder folder = new((JObject) pack) { Parent = parent };
+ Collection.Add(folder);
+ }
+ }
+ }
+
+ // foreach (var folder in Collection)
+ // {
+ // Console.WriteLine(folder);
+ // }
+
+ Collection = Collection.Filter();
+
+ Console.WriteLine($"Total items: {ItemCount}");
+ }
+
+ public IEnumerable Enrties()
+ {
+ foreach (CompendiumFolder folder in Collection.FindAll(f => f.Path is not null))
+ {
+ string dirPath = Path.Combine(Importer.Dir, folder.Path!);
+
+ foreach (string filePath in Directory.GetFiles(dirPath, "*.json", SearchOption.AllDirectories))
+ {
+ FileInfo file = new(filePath);
+
+ if (file.Name == "_folders.json")
{
continue;
}
- var dirPath = Path.Combine(Importer.Dir, parent.Path);
+ using StreamReader reader = new(file.FullName);
+ JObject itemJson = JObject.Parse(reader.ReadToEnd());
- ItemCount += Directory.GetFiles(dirPath, "*.json", SearchOption.AllDirectories)
- .Length;
-
- foreach (var foldersFilePath in Directory.GetFiles(dirPath, "_folders.json", SearchOption.AllDirectories))
+ CompendiumFolder? itemFolder = folder;
+ if (itemJson.TryGetValue("folder", out JToken? itemJsonFolder))
{
- ItemCount--;
- using var file = new StreamReader(foldersFilePath);
- var data = JArray.Parse(file.ReadToEnd());
-
- foreach (var pack in data)
- {
- var folder = new CompendiumFolder((JObject)pack) { Parent = parent };
- Collection.Add(folder);
- }
+ itemFolder = Collection.GetById(itemJsonFolder.ToString());
}
+
+ yield return new LoaderEnrty(file, itemJson, itemFolder ?? folder);
}
-
- // foreach (var folder in Collection)
- // {
- // Console.WriteLine(folder);
- // }
-
- Collection = Collection.Filter();
-
- Console.WriteLine($"Total items: {ItemCount}");
- }
-
- public IEnumerable Enrties()
- {
- foreach (var folder in Collection.FindAll(f => f.Path is not null))
- {
- var dirPath = Path.Combine(Importer.Dir, folder.Path!);
-
- foreach (var filePath in Directory.GetFiles(dirPath, "*.json", SearchOption.AllDirectories))
- {
- var file = new FileInfo(filePath);
-
- if (file.Name == "_folders.json")
- {
- continue;
- }
-
- using var reader = new StreamReader(file.FullName);
- var itemJson = JObject.Parse(reader.ReadToEnd());
-
- var itemFolder = folder;
- if (itemJson.TryGetValue("folder", out var itemJsonFolder))
- {
- itemFolder = Collection.GetById(itemJsonFolder.ToString());
- }
-
- yield return new LoaderEnrty(file, itemJson, itemFolder ?? folder);
- }
- }
- }
-
- public class LoaderEnrty(FileInfo file, JObject itemJson, CompendiumFolder folder)
- {
- public FileInfo File { get; } = file;
- public JObject Json { get; } = itemJson;
- public CompendiumFolder Folder { get; } = folder;
- public string Type { get; } = itemJson["type"]?.ToString()
- ?? throw new Exception($"Expected to have `type` field in file {file.FullName}");
}
}
+
+ public class LoaderEnrty(FileInfo file, JObject itemJson, CompendiumFolder folder)
+ {
+ public FileInfo File { get; } = file;
+ public JObject Json { get; } = itemJson;
+ public CompendiumFolder Folder { get; } = folder;
+ public string Type { get; } = itemJson["type"]?.ToString()
+ ?? throw new Exception($"Expected to have `type` field in file {file.FullName}");
+ }
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/AbstractProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/AbstractProcessor.cs
index f869b5b..a53a4d0 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/AbstractProcessor.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/AbstractProcessor.cs
@@ -1,104 +1,97 @@
using Newtonsoft.Json.Linq;
using NpgsqlTypes;
using Pf2eDataScrapper.Model;
+using Pf2eDataScrapper.Model.Common;
using Pf2eDataScrapper.Model.Enum;
-using System.ComponentModel;
-namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder
+namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder;
+
+internal abstract class AbstractProcessor(JObject input)
{
- internal abstract class AbstractProcessor(JObject input)
+ public readonly Pf2eTestContext Context = new();
+
+ public readonly JObject Input = input;
+
+ protected DataBuilderHelper Helper = DataBuilderHelper.Instance;
+
+ public Entity Entity { get; set; } = new();
+
+ public abstract EntityType Type { get; }
+
+ public abstract IEntity Object { get; }
+
+ public virtual void Process()
{
- public readonly Pf2eTestContext Context = new();
+ Entity.Id = Helper.NextId;
+ Entity.Type = Type;
- public readonly JObject Input = input;
+ Entity.Name = GetRequired("name");
+ Entity.Img = GetRequired("img");
+ Entity.Description = GetRequired("system.description.value");
- protected DataBuilderHelper Helper = DataBuilderHelper.Instance;
+ Entity.IsTranslated = false;
+ Entity.IsChecked = false;
- public Entity Entity { get; set; } = new Entity();
+ Entity.Slug = Helper.GenerateSlug(Entity.Name);
- public abstract EntityType Type { get; }
+ Object.Id = Entity.Id;
- public abstract IEntity Object { get; }
+ Context.Entities.Add(Entity);
- public virtual void Process()
+ // TODO Traits, Alias
+ }
+
+ public void Save()
+ {
+ Context.SaveChanges();
+ }
+
+ public T GetRequired(string path)
+ {
+ JToken token = Input.SelectToken(path) ?? throw new NullReferenceException($"'{path}' is null");
+
+ return token.ToObject() ?? throw new NullReferenceException($"'{path}' is null");
+ }
+
+ public T? GetOptional(string path)
+ {
+ JToken? token = Input.SelectToken(path) ?? null;
+
+ return token is null ? default! : token.ToObject() ?? default;
+ }
+
+ public T EnumRequired(string path) where T : Enum
+ {
+ return EnumOptional(path) ?? throw new Exception($"Can't resolve Enum value for {typeof(T).Name} in path {path}");
+ }
+
+ public T? EnumOptional(string path) where T : Enum
+ {
+ string? value = GetOptional(path);
+
+ if (value == null)
{
- Entity.Id = Helper.NextId;
- Entity.Type = Type;
-
- Entity.Name = GetRequired("name");
- Entity.Img = GetRequired("img");
- Entity.Description = GetRequired("system.description.value");
- Entity.DescriptionGm = GetOptional("system.description.gm");
-
- Entity.IsTranslated = false;
- Entity.IsChecked = false;
-
- Entity.Slug = Helper.GenerateSlug(Entity.Name);
-
- Object.Id = Entity.Id;
-
- Context.Entities.Add(Entity);
-
- // TODO Traits, Alias
- }
-
- public void Save()
- {
- Context.SaveChanges();
- }
-
- public T GetRequired(string path)
- {
- var token = Input.SelectToken(path) ?? throw new NullReferenceException($"'{path}' is null");
-
- return token.ToObject() ?? throw new NullReferenceException($"'{path}' is null");
- }
-
- public T? GetOptional(string path)
- {
- var token = Input.SelectToken(path) ?? null;
-
- if (token is null)
- {
- return default!;
- }
-
- return token.ToObject() ?? default;
- }
-
- public T EnumRequired(string path) where T : Enum
- {
- return EnumOptional(path) ?? throw new Exception($"Can't resolve Enum value for {typeof(T).Name} in path {path}");
- }
-
- public T? EnumOptional(string path) where T : Enum
- {
- string? value = GetOptional(path);
-
- if (value == null)
- {
- return default;
- }
-
- foreach (var field in typeof(T).GetFields())
- {
- if (Attribute.GetCustomAttribute(field, typeof(PgNameAttribute)) is PgNameAttribute attribute)
- {
- if (attribute.PgName == value)
- {
- return (T)field.GetValue(null);
- }
- }
- else
- {
- if (field.Name == value)
- {
- return (T)field.GetValue(null);
- }
- }
- }
-
return default;
}
+
+ foreach (System.Reflection.FieldInfo field in typeof(T).GetFields())
+ {
+ if (Attribute.GetCustomAttribute(field, typeof(PgNameAttribute)) is PgNameAttribute attribute)
+ {
+ if (attribute.PgName == value)
+ {
+ return (T) field.GetValue(null);
+ }
+ }
+ else
+ {
+ if (field.Name == value)
+ {
+ return (T) field.GetValue(null);
+ }
+ }
+ }
+
+ return default;
}
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/DataBuilderHelper.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/DataBuilderHelper.cs
index f41897e..c92002c 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/DataBuilderHelper.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/DataBuilderHelper.cs
@@ -1,28 +1,27 @@
using Slugify;
-namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder
+namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder;
+
+internal class DataBuilderHelper
{
- internal class DataBuilderHelper
+ public Pf2eDatabase Database = Pf2eDatabase.Instance;
+
+ public SlugHelper Slugger = new();
+
+ private DataBuilderHelper()
{
- public Pf2eDatabase Database = Pf2eDatabase.Instance;
-
- public SlugHelper Slugger = new();
-
- private DataBuilderHelper()
- {
- }
-
- private int _id = 0;
-
- public int NextId { get => ++_id; }
-
- public string GenerateSlug(string name)
- {
- return Slugger.GenerateSlug(name);
- }
-
-
-
- public readonly static DataBuilderHelper Instance = new();
}
+
+ private int _id = 0;
+
+ public int NextId { get => ++_id; }
+
+ public string GenerateSlug(string name)
+ {
+ return Slugger.GenerateSlug(name);
+ }
+
+
+
+ public static readonly DataBuilderHelper Instance = new();
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/PF2eFoundryDataBuilder.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/PF2eFoundryDataBuilder.cs
index 4306edb..9ad4f57 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/PF2eFoundryDataBuilder.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/PF2eFoundryDataBuilder.cs
@@ -3,84 +3,78 @@ using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium;
using System.Reflection;
-namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder
+namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder;
+
+internal class PF2eFoundryDataBuilder
{
- internal class PF2eFoundryDataBuilder
+ public Pf2eDatabase Database = Pf2eDatabase.Instance;
+
+ ///
+ /// Загрузчик данных.
+ ///
+ public readonly CompendiumLoader Loader;
+
+ ///
+ /// Коллекция папок компендиума.
+ ///
+ public CompendiumFolderCollection Collection => Loader.Collection;
+
+ public Dictionary Processors = [];
+
+ public PF2eFoundryDataBuilder(CompendiumLoader loader)
{
- public Pf2eDatabase Database = Pf2eDatabase.Instance;
+ Loader = loader;
+ PrepareProcessors();
+ }
- ///
- /// Загрузчик данных.
- ///
- public readonly CompendiumLoader Loader;
-
- ///
- /// Коллекция папок компендиума.
- ///
- public CompendiumFolderCollection Collection => Loader.Collection;
-
- public Dictionary Processors = [];
-
- public PF2eFoundryDataBuilder(CompendiumLoader loader)
+ public void PrepareProcessors()
+ {
+ foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
- Loader = loader;
- PrepareProcessors();
- }
-
- public void PrepareProcessors()
- {
- foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
+ if (type.GetCustomAttributes(typeof(Pf2eTypeProcessor), true).Length <= 0)
{
- if (type.GetCustomAttributes(typeof(Pf2eTypeProcessor), true).Length <= 0)
- {
- continue;
- }
- var attribute = type.GetCustomAttribute();
- Processors.Add(attribute!.Type, type.GetConstructor(new[] { typeof(JObject) })!);
+ continue;
}
- }
-
- public AbstractProcessor? GetProcessor(string type, JObject input)
- {
- if (Processors.TryGetValue(type, out var constructor))
- {
- return (AbstractProcessor)constructor.Invoke([input]);
- }
-
- return null;
- }
-
- public void TruncateTables()
- {
- Console.WriteLine("Truncating all old data...");
-
- Database.ExecuteCommand("SELECT f_truncate_tables();");
-
- Console.WriteLine("Truncation completed!");
- }
-
- public void Build()
- {
- Console.WriteLine("Building data...");
-
- var bar = new ProgressBar(Loader.ItemCount);
- var i = 0;
-
- foreach (var entry in Loader.Enrties())
- {
- bar.Refresh(i++, $"{entry.Folder.Name}/{entry.File.Name}");
-
- var processor = GetProcessor($"{entry.Folder.Type}.{entry.Type}", entry.Json);
- if (processor is null)
- {
- continue;
- }
-
- processor.Process();
- processor.Save();
- }
-
- bar.Refresh(Loader.ItemCount, "Done!");
+ Pf2eTypeProcessor? attribute = type.GetCustomAttribute();
+ Processors.Add(attribute!.Type, type.GetConstructor([typeof(JObject)])!);
}
}
+
+ public AbstractProcessor? GetProcessor(string type, JObject input)
+ {
+ return Processors.TryGetValue(type, out ConstructorInfo? constructor) ? (AbstractProcessor) constructor.Invoke([input]) : null;
+ }
+
+ public void TruncateTables()
+ {
+ Console.WriteLine("Truncating all old data...");
+
+ Database.ExecuteCommand("SELECT f_truncate_tables();");
+
+ Console.WriteLine("Truncation completed!");
+ }
+
+ public void Build()
+ {
+ Console.WriteLine("Building data...");
+
+ ProgressBar bar = new(Loader.ItemCount);
+ int i = 0;
+
+ foreach (CompendiumLoader.LoaderEnrty entry in Loader.Enrties())
+ {
+ bar.Refresh(i++, $"{entry.Folder.Name}/{entry.File.Name}");
+
+ AbstractProcessor? processor = GetProcessor($"{entry.Folder.Type}.{entry.Type}", entry.Json);
+ if (processor is null)
+ {
+ continue;
+ }
+
+ processor.Process();
+ processor.Save();
+ }
+
+ bar.Refresh(Loader.ItemCount, "Done!");
+ }
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Pf2eTypeProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Pf2eTypeProcessor.cs
index e3609c1..7e5e37a 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Pf2eTypeProcessor.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Pf2eTypeProcessor.cs
@@ -1,10 +1,9 @@
-namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder
-{
- [AttributeUsage(AttributeTargets.Class)]
- internal class Pf2eTypeProcessor(string type, int priority = 0) : Attribute
- {
- public readonly string Type = type;
+namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder;
- public readonly int Priority = priority;
- }
+[AttributeUsage(AttributeTargets.Class)]
+internal class Pf2eTypeProcessor(string type, int priority = 0) : Attribute
+{
+ public readonly string Type = type;
+
+ public readonly int Priority = priority;
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Processors/ConditionProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Processors/ConditionProcessor.cs
index 9ec2eb4..7964365 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Processors/ConditionProcessor.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Processors/ConditionProcessor.cs
@@ -2,32 +2,31 @@
using Pf2eDataScrapper.Model;
using Pf2eDataScrapper.Model.Enum;
-namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder.Processors
+namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder.Processors;
+
+[Pf2eTypeProcessor("Item.condition")]
+internal class ConditionProcessor(JObject input) : AbstractProcessor(input)
{
- [Pf2eTypeProcessor("Item.condition")]
- internal class ConditionProcessor(JObject input) : AbstractProcessor(input)
+ public override EntityType Type => EntityType.Condition;
+
+ public override Condition Object { get; } = new();
+
+ public override void Process()
{
- public override EntityType Type => EntityType.Condition;
+ base.Process();
- public override Condition Object { get; } = new();
-
- public override void Process()
+ JObject extra = new()
{
- base.Process();
+ { "duration", Input.SelectToken("system.duration") },
+ { "overrides", Input.SelectToken("system.overrides") },
+ { "references", Input.SelectToken("system.references") },
+ { "value", Input.SelectToken("system.value") }
+ };
- JObject extra = new()
- {
- { "duration", Input.SelectToken("system.duration") },
- { "overrides", Input.SelectToken("system.overrides") },
- { "references", Input.SelectToken("system.references") },
- { "value", Input.SelectToken("system.value") }
- };
+ Object.Extra = extra.ToString(Newtonsoft.Json.Formatting.Indented);
- Object.Extra = extra.ToString(Newtonsoft.Json.Formatting.Indented);
+ Object.Group = EnumOptional("system.group");
- Object.Group = EnumOptional("system.group");
-
- Context.Conditions.Add(Object);
- }
+ Context.Conditions.Add(Object);
}
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Pf2eFoundryImporter.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Pf2eFoundryImporter.cs
index 7944ad1..9baf816 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Pf2eFoundryImporter.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Pf2eFoundryImporter.cs
@@ -2,66 +2,65 @@
using Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.SchemaBuilder;
using Pf2eDataScrapper.Importers.Repositories;
-namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry
+namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry;
+
+///
+/// Импортёр для модуля Pf2e FoundryVTT.
+///
+internal class Pf2EFoundryImporter : AbstractImporter
{
///
- /// Импортёр для модуля Pf2e FoundryVTT.
+ /// Отображаемое имя импортёра.
///
- internal class Pf2EFoundryImporter : AbstractImporter
+ public override string Name => "Pf2e FoundryVTT module";
+
+ ///
+ /// Короткое имя импортёра.
+ ///
+ public override string Slug => "pf2e";
+
+ public override AbstractImporterRepository Repository => new GitRepository(this, "https://github.com/foundryvtt/pf2e.git");
+
+ ///
+ /// Загрузчик данных компендиума.
+ ///
+ public CompendiumLoader Loader { get; }
+
+ ///
+ /// Конструктор импортёра.
+ ///
+ public Pf2EFoundryImporter()
{
- ///
- /// Отображаемое имя импортёра.
- ///
- public override string Name => "Pf2e FoundryVTT module";
+ Loader = new CompendiumLoader(this);
+ }
- ///
- /// Короткое имя импортёра.
- ///
- public override string Slug => "pf2e";
+ ///
+ /// Метод подготовки данных для импорта.
+ ///
+ public override void Prepare()
+ {
+ Loader.Prepare();
+ }
- public override AbstractImporterRepository Repository => new GitRepository(this, "https://github.com/foundryvtt/pf2e.git");
+ ///
+ /// Импорт данных.
+ ///
+ public override void Import()
+ {
+ PF2eFoundryDataBuilder builder = new(Loader);
- ///
- /// Загрузчик данных компендиума.
- ///
- public CompendiumLoader Loader { get; }
+ builder.TruncateTables();
+ builder.Build();
+ }
- ///
- /// Конструктор импортёра.
- ///
- public Pf2EFoundryImporter()
- {
- Loader = new CompendiumLoader(this);
- }
+ ///
+ /// Построение схем данных
+ ///
+ public override void BuildSchemas()
+ {
+ CompendiumSchemaBuilder builder = new(Loader);
- ///
- /// Метод подготовки данных для импорта.
- ///
- public override void Prepare()
- {
- Loader.Prepare();
- }
-
- ///
- /// Импорт данных.
- ///
- public override void Import()
- {
- var builder = new PF2eFoundryDataBuilder(Loader);
-
- builder.TruncateTables();
- builder.Build();
- }
-
- ///
- /// Построение схем данных
- ///
- public override void BuildSchemas()
- {
- var builder = new CompendiumSchemaBuilder(Loader);
-
- builder.BuildSchemas();
- builder.Save(EnvSettings.OutputDir);
- }
+ builder.BuildSchemas();
+ builder.Save(EnvSettings.OutputDir);
}
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/SchemaBuilder/CompendiumSchemaBuilder.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/SchemaBuilder/CompendiumSchemaBuilder.cs
index 87befb9..906ba91 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/SchemaBuilder/CompendiumSchemaBuilder.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/SchemaBuilder/CompendiumSchemaBuilder.cs
@@ -2,191 +2,185 @@
using Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium;
using Pf2eDataScrapper.SchemaBuilder;
-namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.SchemaBuilder
+namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.SchemaBuilder;
+
+///
+/// Класс построения схемы компендиумов.
+///
+/// Загрузчик данных.
+internal class CompendiumSchemaBuilder(CompendiumLoader loader)
{
///
- /// Класс построения схемы компендиумов.
+ /// Загрузчик данных.
///
- /// Загрузчик данных.
- internal class CompendiumSchemaBuilder(CompendiumLoader loader)
+ public CompendiumLoader Loader = loader;
+
+ ///
+ /// Коллекция папок компендиума.
+ ///
+ public CompendiumFolderCollection Collection = loader.Collection;
+
+ ///
+ /// Объект для определения типов полей в компендиумах PF2E.
+ ///
+ public CompendiumSchemaTypeResolver Resolver = new();
+
+ ///
+ /// Схемы данных по папкам.
+ ///
+ public Dictionary PackSchemas = [];
+
+ ///
+ /// Схемы данных по типам.
+ ///
+ public Dictionary TypeSchemas = [];
+
+ private readonly string[] _equipmentTypes = ["equipment", "armor", "backpack", "consumable", "kit", "shield", "treasure", "weapon"];
+
+ private SchemaNode GetPackSchema(CompendiumFolder folder)
{
- ///
- /// Загрузчик данных.
- ///
- public CompendiumLoader Loader = loader;
-
- ///
- /// Коллекция папок компендиума.
- ///
- public CompendiumFolderCollection Collection = loader.Collection;
-
- ///
- /// Объект для определения типов полей в компендиумах PF2E.
- ///
- public CompendiumSchemaTypeResolver Resolver = new();
-
- ///
- /// Схемы данных по папкам.
- ///
- public Dictionary PackSchemas = [];
-
- ///
- /// Схемы данных по типам.
- ///
- 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))
{
- if (!PackSchemas.TryGetValue(folder, out SchemaNode? value))
+ value = new SchemaNode()
{
- value = new SchemaNode()
- {
- Resolver = Resolver,
- Path = folder.Name
- };
- PackSchemas[folder] = value;
- }
-
- return value;
+ Resolver = Resolver,
+ Path = folder.Name
+ };
+ PackSchemas[folder] = 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;
+ }
- return value;
+ private SchemaNode GetTypeSchema(string key)
+ {
+ if (!TypeSchemas.TryGetValue(key, out SchemaNode? value))
+ {
+ value = new SchemaNode()
+ {
+ Resolver = Resolver,
+ Path = key
+ };
+ TypeSchemas[key] = value;
}
- ///
- /// Получение набора схем, к которым относится проверяемый объект.
- ///
- /// Папка компендиума, в которой находится объект.
- /// Указанный тип объекта.
- ///
- protected List GetItemSchemas(CompendiumFolder folder, string? itemType)
- {
- var key = folder.Type.ToString() + (itemType is not null ? $".{itemType}" : "");
+ return value;
+ }
- if (_equipmentTypes.Contains(itemType))
+ ///
+ /// Получение набора схем, к которым относится проверяемый объект.
+ ///
+ /// Папка компендиума, в которой находится объект.
+ /// Указанный тип объекта.
+ ///
+ protected List GetItemSchemas(CompendiumFolder folder, string? itemType)
+ {
+ string key = folder.Type.ToString() + (itemType is not null ? $".{itemType}" : "");
+
+ return _equipmentTypes.Contains(itemType)
+ ? [GetPackSchema(folder), GetTypeSchema(key), GetTypeSchema("Equipment")]
+ : [GetPackSchema(folder), GetTypeSchema(key)];
+ }
+
+ ///
+ /// Построение схем данных.
+ ///
+ public void BuildSchemas()
+ {
+ Console.WriteLine("Building schemas...");
+
+ ProgressBar bar = new(Loader.ItemCount);
+ int i = 0;
+
+ foreach (CompendiumLoader.LoaderEnrty entry in Loader.Enrties())
+ {
+ bar.Refresh(i++, entry.Folder.Name);
+
+ List schemas = GetItemSchemas(entry.Folder, entry.Type);
+
+ foreach (SchemaNode schema in schemas)
{
- return [GetPackSchema(folder), GetTypeSchema(key), GetTypeSchema("Equipment")];
- }
- else
- {
- return [GetPackSchema(folder), GetTypeSchema(key)];
+ schema.AddValue(entry.Json);
}
}
- ///
- /// Построение схем данных.
- ///
- public void BuildSchemas()
+ bar.Refresh(Loader.ItemCount, "Done!");
+ }
+
+ ///
+ /// Сохранение данных.
+ ///
+ /// Папка для сохранения.
+ public void Save(string targetDir)
+ {
+ Console.WriteLine("Dumping schemas...");
+
+ ProgressBar bar = new(PackSchemas.Count + TypeSchemas.Count);
+ int i = 0;
+
+ targetDir = Path.Combine(targetDir, Loader.Importer.Slug);
+
+ if (!Directory.Exists(targetDir))
{
- Console.WriteLine("Building schemas...");
+ Directory.CreateDirectory(targetDir);
+ }
+ Array.ForEach(Directory.GetFiles(@targetDir), File.Delete);
- var bar = new ProgressBar(Loader.ItemCount);
- var i = 0;
+ // Packs
+ string packsDir = Path.Combine(targetDir, "packs");
+ Directory.CreateDirectory(packsDir);
- foreach (var entry in Loader.Enrties())
- {
- bar.Refresh(i++, entry.Folder.Name);
-
- var schemas = GetItemSchemas(entry.Folder, entry.Type);
-
- foreach (var schema in schemas)
- {
- schema.AddValue(entry.Json);
- }
- }
-
- bar.Refresh(Loader.ItemCount, "Done!");
+ foreach (KeyValuePair pair in PackSchemas)
+ {
+ bar.Refresh(i++, pair.Key.Name);
+ SaveSchema(packsDir, pair.Key.Name, pair.Value);
}
- ///
- /// Сохранение данных.
- ///
- /// Папка для сохранения.
- public void Save(string targetDir)
+ // Types
+ string typesDir = Path.Combine(targetDir, "types");
+ Directory.CreateDirectory(typesDir);
+ foreach (KeyValuePair pair in TypeSchemas)
{
- Console.WriteLine("Dumping schemas...");
-
- var bar = new ProgressBar(PackSchemas.Count + TypeSchemas.Count);
- var i = 0;
-
- targetDir = Path.Combine(targetDir, Loader.Importer.Slug);
-
- if (!Directory.Exists(targetDir))
- {
- Directory.CreateDirectory(targetDir);
- }
- Array.ForEach(Directory.GetFiles(@targetDir), File.Delete);
-
- // Packs
- var packsDir = Path.Combine(targetDir, "packs");
- Directory.CreateDirectory(packsDir);
-
- foreach (var pair in PackSchemas)
- {
- bar.Refresh(i++, pair.Key.Name);
- SaveSchema(packsDir, pair.Key.Name, pair.Value);
- }
-
- // Types
- var typesDir = Path.Combine(targetDir, "types");
- Directory.CreateDirectory(typesDir);
- foreach (var pair in TypeSchemas)
- {
- bar.Refresh(i++, pair.Key);
- SaveSchema(typesDir, pair.Key, pair.Value);
- }
-
- Console.WriteLine("Done!");
+ bar.Refresh(i++, pair.Key);
+ SaveSchema(typesDir, pair.Key, pair.Value);
}
- ///
- /// Сохранение конкретной схемы.
- ///
- /// Корневая папка для сохранения этой категории схем.
- /// Название сохраняемой схемы.
- /// Сохраняемая схема.
- protected void SaveSchema(string dir, string name, SchemaNode schema)
+ Console.WriteLine("Done!");
+ }
+
+ ///
+ /// Сохранение конкретной схемы.
+ ///
+ /// Корневая папка для сохранения этой категории схем.
+ /// Название сохраняемой схемы.
+ /// Сохраняемая схема.
+ protected void SaveSchema(string dir, string name, SchemaNode schema)
+ {
+ char[] invalids = Path.GetInvalidFileNameChars();
+ string fileName = string.Join("_", schema.Path.Split(invalids, StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.');
+
+ string path = Path.Combine(dir, fileName + ".yaml");
+
+ string? dirPath = Path.GetDirectoryName(path);
+
+ if (dirPath is not null && !Directory.Exists(dirPath))
{
- var invalids = Path.GetInvalidFileNameChars();
- var fileName = string.Join("_", schema.Path.Split(invalids, StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.');
-
- var path = Path.Combine(dir, fileName + ".yaml");
-
- var dirPath = Path.GetDirectoryName(path);
-
- if (dirPath is not null && !Directory.Exists(dirPath))
- {
- Directory.CreateDirectory(dirPath);
- }
-
- using var writer = new StreamWriter(path);
-
- schema.Beautify();
-
- 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());
+ Directory.CreateDirectory(dirPath);
}
+
+ using StreamWriter writer = new(path);
+
+ schema.Beautify();
+
+ 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/SchemaBuilder/CompendiumSchemaTypeResolver.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/SchemaBuilder/CompendiumSchemaTypeResolver.cs
index 0808051..370b5eb 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/SchemaBuilder/CompendiumSchemaTypeResolver.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/SchemaBuilder/CompendiumSchemaTypeResolver.cs
@@ -2,61 +2,52 @@
using Pf2eDataScrapper.SchemaBuilder;
using Pf2eDataScrapper.SchemaBuilder.Types;
-namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.SchemaBuilder
+namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.SchemaBuilder;
+
+internal class CompendiumSchemaTypeResolver : TypeResolver
{
- internal class CompendiumSchemaTypeResolver : TypeResolver
+ public class FoundryRulesSchemaType(SchemaNode parent) : IgnoreSchemaType(parent)
{
- public class FoundryRulesSchemaType(SchemaNode parent) : IgnoreSchemaType(parent)
+ public override string GetTypeName()
{
- public override string GetTypeName()
- {
- return "ignored (Foundry rules object)";
- }
- }
-
- protected readonly List DictionaryPaths = [
- "Actor.character.items.[].system.items",
- "Actor.character.items.[].system.overlays",
- "Item.ancestry.system.items",
- "Item.ancestry.system.boosts",
- "Item.background.system.boosts",
- "Item.background.system.items",
- "Item.class.system.items",
- "Item.consumable.system.spell.system.damage",
- "Item.consumable.system.spell.system.overlays",
- "Item.deity.system.spells",
- "Item.feat.system.subfeatures.proficiencies",
- "Item.kit.system.items",
- "Item.kit.system.items.[value].items",
- "Item.spell.system.damage",
- "Item.spell.system.heightening.damage",
- "Item.spell.system.heightening.levels",
- "Item.spell.system.heightening.levels.[value].damage",
- "Item.spell.system.overlays",
- "Item.spell.system.overlays.[value].system.damage",
- "Item.spell.system.overlays.[value].system.heightening",
- "Item.spell.system.overlays.[value].system.heightening.[value]"
- ];
-
- ///
- /// Частное определение типа поля.
- ///
- /// Поле схемы данных, для которого создаётся тип.
- /// Добавляемое значение.
- /// Новый тип для схемы данных. `null`, что бы использовать значение по умолчанию
- protected override AbstractSchemaType? CustomResolve(SchemaNode node, JToken? value)
- {
- if (CheckPath(node, DictionaryPaths))
- {
- return new DictionarySchemaType(node);
- }
-
- if (node.Path.EndsWith(".rules"))
- {
- return new FoundryRulesSchemaType(node);
- }
-
- return null;
+ return "ignored (Foundry rules object)";
}
}
+
+ protected readonly List DictionaryPaths = [
+ "Actor.character.items.[].system.items",
+ "Actor.character.items.[].system.overlays",
+ "Item.ancestry.system.items",
+ "Item.ancestry.system.boosts",
+ "Item.background.system.boosts",
+ "Item.background.system.items",
+ "Item.class.system.items",
+ "Item.consumable.system.spell.system.damage",
+ "Item.consumable.system.spell.system.overlays",
+ "Item.deity.system.spells",
+ "Item.feat.system.subfeatures.proficiencies",
+ "Item.kit.system.items",
+ "Item.kit.system.items.[value].items",
+ "Item.spell.system.damage",
+ "Item.spell.system.heightening.damage",
+ "Item.spell.system.heightening.levels",
+ "Item.spell.system.heightening.levels.[value].damage",
+ "Item.spell.system.overlays",
+ "Item.spell.system.overlays.[value].system.damage",
+ "Item.spell.system.overlays.[value].system.heightening",
+ "Item.spell.system.overlays.[value].system.heightening.[value]"
+ ];
+
+ ///
+ /// Частное определение типа поля.
+ ///
+ /// Поле схемы данных, для которого создаётся тип.
+ /// Добавляемое значение.
+ /// Новый тип для схемы данных. `null`, что бы использовать значение по умолчанию
+ protected override AbstractSchemaType? CustomResolve(SchemaNode node, JToken? value)
+ {
+ return CheckPath(node, DictionaryPaths)
+ ? new DictionarySchemaType(node)
+ : node.Path.EndsWith(".rules") ? new FoundryRulesSchemaType(node) : (AbstractSchemaType?) null;
+ }
}
diff --git a/Pf2eDataScrapper/Importers/Repositories/AbstractImporterRepository.cs b/Pf2eDataScrapper/Importers/Repositories/AbstractImporterRepository.cs
index 42b08a3..4f4298f 100644
--- a/Pf2eDataScrapper/Importers/Repositories/AbstractImporterRepository.cs
+++ b/Pf2eDataScrapper/Importers/Repositories/AbstractImporterRepository.cs
@@ -1,13 +1,12 @@
-namespace Pf2eDataScrapper.Importers.Repositories
+namespace Pf2eDataScrapper.Importers.Repositories;
+
+internal abstract class AbstractImporterRepository(AbstractImporter importer)
{
- internal abstract class AbstractImporterRepository (AbstractImporter importer)
- {
- public readonly AbstractImporter Importer = importer;
+ public readonly AbstractImporter Importer = importer;
- public string RepositoryDirPath => Importer.Dir;
+ public string RepositoryDirPath => Importer.Dir;
- public DirectoryInfo RepositoryDir => new(RepositoryDirPath);
+ public DirectoryInfo RepositoryDir => new(RepositoryDirPath);
- public abstract void Update();
- }
+ public abstract void Update();
}
diff --git a/Pf2eDataScrapper/Importers/Repositories/GitRepository.cs b/Pf2eDataScrapper/Importers/Repositories/GitRepository.cs
index 45e604a..3f419f9 100644
--- a/Pf2eDataScrapper/Importers/Repositories/GitRepository.cs
+++ b/Pf2eDataScrapper/Importers/Repositories/GitRepository.cs
@@ -1,52 +1,50 @@
-using System.Data.Common;
-using System.Diagnostics;
+using System.Diagnostics;
-namespace Pf2eDataScrapper.Importers.Repositories
+namespace Pf2eDataScrapper.Importers.Repositories;
+
+///
+/// Загрузчик данных из git-репозиториев
+///
+///
+internal class GitRepository(AbstractImporter importer, string url) : AbstractImporterRepository(importer)
{
+ public readonly string Url = url;
+
///
- /// Загрузчик данных из git-репозиториев
+ /// Обновление импортёра
///
- ///
- internal class GitRepository(AbstractImporter importer, string url) : AbstractImporterRepository(importer)
+ public override void Update()
{
- public readonly string Url = url;
+ string gitPath = Path.Combine(RepositoryDirPath, importer.Slug);
- ///
- /// Обновление импортёра
- ///
- public override void Update()
+ if (Directory.Exists(gitPath))
{
- var gitPath = Path.Combine(RepositoryDirPath, importer.Slug);
-
- if (Directory.Exists(gitPath))
+ // git pull
+ Process process = new()
{
- // git pull
- var process = new Process
+ StartInfo = new ProcessStartInfo()
{
- StartInfo = new ProcessStartInfo()
- {
- FileName = "git",
- WorkingDirectory = gitPath,
- Arguments = "pull",
- }
- };
- process.Start();
- }
- else
+ FileName = "git",
+ WorkingDirectory = gitPath,
+ Arguments = "pull",
+ }
+ };
+ process.Start();
+ }
+ else
+ {
+ // git clone
+ Process process = new()
{
- // git clone
- var process = new Process
+ StartInfo = new ProcessStartInfo()
{
- StartInfo = new ProcessStartInfo()
- {
- FileName = "git",
- WorkingDirectory = RepositoryDirPath,
- Arguments = $"clone {Url} {Importer.Slug}",
- }
- };
- process.Start();
+ FileName = "git",
+ WorkingDirectory = RepositoryDirPath,
+ Arguments = $"clone {Url} {Importer.Slug}",
+ }
+ };
+ process.Start();
- }
}
}
}
diff --git a/Pf2eDataScrapper/Model/Action.cs b/Pf2eDataScrapper/Model/Action.cs
index 06a0fa8..1d4b0ae 100644
--- a/Pf2eDataScrapper/Model/Action.cs
+++ b/Pf2eDataScrapper/Model/Action.cs
@@ -1,5 +1,4 @@
using Pf2eDataScrapper.Model.Common;
-using Pf2eDataScrapper.Model.Enum;
namespace Pf2eDataScrapper.Model;
diff --git a/Pf2eDataScrapper/Model/Ancestry.cs b/Pf2eDataScrapper/Model/Ancestry.cs
index 3de866b..86ba142 100644
--- a/Pf2eDataScrapper/Model/Ancestry.cs
+++ b/Pf2eDataScrapper/Model/Ancestry.cs
@@ -1,5 +1,4 @@
using Pf2eDataScrapper.Model.Common;
-using Pf2eDataScrapper.Model.Enum;
namespace Pf2eDataScrapper.Model;
diff --git a/Pf2eDataScrapper/Model/Background.cs b/Pf2eDataScrapper/Model/Background.cs
index c68b325..fdb2897 100644
--- a/Pf2eDataScrapper/Model/Background.cs
+++ b/Pf2eDataScrapper/Model/Background.cs
@@ -1,5 +1,4 @@
using Pf2eDataScrapper.Model.Common;
-using Pf2eDataScrapper.Model.Enum;
namespace Pf2eDataScrapper.Model;
diff --git a/Pf2eDataScrapper/Model/CampaignFeature.cs b/Pf2eDataScrapper/Model/CampaignFeature.cs
index d0df20b..d0da0fe 100644
--- a/Pf2eDataScrapper/Model/CampaignFeature.cs
+++ b/Pf2eDataScrapper/Model/CampaignFeature.cs
@@ -1,5 +1,4 @@
using Pf2eDataScrapper.Model.Common;
-using Pf2eDataScrapper.Model.Enum;
namespace Pf2eDataScrapper.Model;
diff --git a/Pf2eDataScrapper/Model/Class.cs b/Pf2eDataScrapper/Model/Class.cs
index 4b21563..7b83a44 100644
--- a/Pf2eDataScrapper/Model/Class.cs
+++ b/Pf2eDataScrapper/Model/Class.cs
@@ -1,5 +1,4 @@
using Pf2eDataScrapper.Model.Common;
-using Pf2eDataScrapper.Model.Enum;
namespace Pf2eDataScrapper.Model;
diff --git a/Pf2eDataScrapper/Model/Deity.cs b/Pf2eDataScrapper/Model/Deity.cs
index eb15c81..1527f3a 100644
--- a/Pf2eDataScrapper/Model/Deity.cs
+++ b/Pf2eDataScrapper/Model/Deity.cs
@@ -1,5 +1,4 @@
using Pf2eDataScrapper.Model.Common;
-using Pf2eDataScrapper.Model.Enum;
namespace Pf2eDataScrapper.Model;
diff --git a/Pf2eDataScrapper/Model/Enum/EntityRarity.cs b/Pf2eDataScrapper/Model/Enum/EntityRarity.cs
index 2850e8f..49209e4 100644
--- a/Pf2eDataScrapper/Model/Enum/EntityRarity.cs
+++ b/Pf2eDataScrapper/Model/Enum/EntityRarity.cs
@@ -1,19 +1,18 @@
using NpgsqlTypes;
-namespace Pf2eDataScrapper.Model.Enum
+namespace Pf2eDataScrapper.Model.Enum;
+
+public enum EntityRarity
{
- public enum EntityRarity
- {
- [PgName("common")]
- Common,
+ [PgName("common")]
+ Common,
- [PgName("uncommon")]
- Uncommon,
+ [PgName("uncommon")]
+ Uncommon,
- [PgName("rare")]
- Rare,
+ [PgName("rare")]
+ Rare,
- [PgName("unique")]
- Unique
- }
+ [PgName("unique")]
+ Unique
}
diff --git a/Pf2eDataScrapper/Model/Enum/TraitType.cs b/Pf2eDataScrapper/Model/Enum/TraitType.cs
index ceca1e1..2368b79 100644
--- a/Pf2eDataScrapper/Model/Enum/TraitType.cs
+++ b/Pf2eDataScrapper/Model/Enum/TraitType.cs
@@ -1,13 +1,12 @@
using NpgsqlTypes;
-namespace Pf2eDataScrapper.Model.Enum
-{
- public enum TraitType
- {
- [PgName("regular")]
- Regular,
+namespace Pf2eDataScrapper.Model.Enum;
- [PgName("tradition")]
- Tradition
- }
+public enum TraitType
+{
+ [PgName("regular")]
+ Regular,
+
+ [PgName("tradition")]
+ Tradition
}
diff --git a/Pf2eDataScrapper/Model/Feat.cs b/Pf2eDataScrapper/Model/Feat.cs
index 2876981..b020032 100644
--- a/Pf2eDataScrapper/Model/Feat.cs
+++ b/Pf2eDataScrapper/Model/Feat.cs
@@ -1,5 +1,4 @@
using Pf2eDataScrapper.Model.Common;
-using Pf2eDataScrapper.Model.Enum;
namespace Pf2eDataScrapper.Model;
diff --git a/Pf2eDataScrapper/Model/Heritage.cs b/Pf2eDataScrapper/Model/Heritage.cs
index bacfdff..f2ef764 100644
--- a/Pf2eDataScrapper/Model/Heritage.cs
+++ b/Pf2eDataScrapper/Model/Heritage.cs
@@ -1,5 +1,4 @@
using Pf2eDataScrapper.Model.Common;
-using Pf2eDataScrapper.Model.Enum;
namespace Pf2eDataScrapper.Model;
diff --git a/Pf2eDataScrapper/Model/IEntity.cs b/Pf2eDataScrapper/Model/IEntity.cs
index aac682f..27f2018 100644
--- a/Pf2eDataScrapper/Model/IEntity.cs
+++ b/Pf2eDataScrapper/Model/IEntity.cs
@@ -1,12 +1,11 @@
using Pf2eDataScrapper.Model.Common;
-namespace Pf2eDataScrapper.Model
+namespace Pf2eDataScrapper.Model;
+
+internal interface IEntity
{
- internal interface IEntity
- {
- public int Id { get; set; }
+ public int Id { get; set; }
- public Entity Entity { get; set; }
+ public Entity Entity { get; set; }
- }
}
diff --git a/Pf2eDataScrapper/Model/Spell.cs b/Pf2eDataScrapper/Model/Spell.cs
index 9711dad..93fb1b2 100644
--- a/Pf2eDataScrapper/Model/Spell.cs
+++ b/Pf2eDataScrapper/Model/Spell.cs
@@ -1,5 +1,4 @@
using Pf2eDataScrapper.Model.Common;
-using Pf2eDataScrapper.Model.Enum;
namespace Pf2eDataScrapper.Model;
diff --git a/Pf2eDataScrapper/Pf2eDatabase.cs b/Pf2eDataScrapper/Pf2eDatabase.cs
index b2187a2..cc3ddad 100644
--- a/Pf2eDataScrapper/Pf2eDatabase.cs
+++ b/Pf2eDataScrapper/Pf2eDatabase.cs
@@ -1,123 +1,122 @@
using Npgsql;
using System.Text.RegularExpressions;
-namespace Pf2eDataScrapper
+namespace Pf2eDataScrapper;
+
+public partial class Pf2eDatabase
{
- public partial class Pf2eDatabase
+ public NpgsqlConnection Connection;
+
+ public readonly string Username;
+ public readonly string DatabaseName;
+
+
+ private Pf2eDatabase()
{
- public NpgsqlConnection Connection;
+ Username = UsernamePattern().Match(EnvSettings.DatabaseConnection).Groups[1].Value;
+ DatabaseName = DatabaseNamePattern().Match(EnvSettings.DatabaseConnection).Groups[1].Value;
- public readonly string Username;
- public readonly string DatabaseName;
-
-
- private Pf2eDatabase()
- {
- Username = UsernamePattern().Match(EnvSettings.DatabaseConnection).Groups[1].Value;
- DatabaseName = DatabaseNamePattern().Match(EnvSettings.DatabaseConnection).Groups[1].Value;
-
- Connection = new NpgsqlConnection(EnvSettings.DatabaseConnection);
- Connection.Open();
- }
-
- ~Pf2eDatabase()
- {
- Connection.Close();
- }
-
- public static Pf2eDatabase Instance { get; } = new();
-
- public NpgsqlTransaction? Transaction { get; private set; }
-
- public void StartTransaction()
- {
- if (Transaction != null)
- {
- throw new InvalidOperationException("Transaction already started.");
- }
-
- Transaction = Connection.BeginTransaction();
- }
-
- public void Commit()
- {
- if (Transaction == null)
- {
- throw new InvalidOperationException("No transaction started.");
- }
-
- Transaction.Commit();
- }
-
- public void ExecuteCommand(string sql)
- {
- var command = GetCommand(sql);
-
- command.ExecuteNonQuery();
- }
-
- public NpgsqlCommand GetCommand(string sql)
- {
- return new NpgsqlCommand(sql, Connection);
- }
-
-
-
-
- /*
- public void RebuildDatabase()
- {
- // Закрываем текущее соединение
- Connection.Close();
-
- // Получение имён
- var databaseNamePattern = DatabaseNamePattern();
- var userConnection = databaseNamePattern.Replace(EnvSettings.DatabaseConnection, ";");
- var databaseName = databaseNamePattern.Match(EnvSettings.DatabaseConnection).Groups[1].Value;
- var username = UserNamePattern().Match(EnvSettings.DatabaseConnection).Groups[1].Value;
-
- // Временное подключение к базе данных
- NpgsqlConnection tmpConnection = new(userConnection);
- tmpConnection.Open();
-
- // Удаляем базу данных
- NpgsqlCommand dropCommand = new($"DROP DATABASE \"{databaseName}\";", tmpConnection);
- dropCommand.ExecuteNonQuery();
-
- // Создаём новую базу данных
- NpgsqlCommand createCommand = new($@"
- CREATE DATABASE {databaseName}
- WITH OWNER = {username}
- ENCODING = 'UTF8'
- CONNECTION LIMIT = -1;
- ", tmpConnection);
- createCommand.ExecuteNonQuery();
-
- string[] permissionCommands = [
- $"GRANT TEMPORARY, CONNECT ON DATABASE {databaseName} TO PUBLIC;",
- $"GRANT ALL ON DATABASE {databaseName} TO {username} WITH GRANT OPTION;",
- $"GRANT ALL ON DATABASE {databaseName} TO postgres;"
- ];
-
- foreach (var command in permissionCommands)
- {
- NpgsqlCommand permissionCommand = new(command, tmpConnection);
- permissionCommand.ExecuteNonQuery();
- }
-
- // Закрываем временное соединение
- tmpConnection.Close();
-
- // Заново создаём соединение
- Connection = new NpgsqlConnection(EnvSettings.DatabaseConnection);
- }
-
- */
-
- [GeneratedRegex(@"(?:^|;)Database=(.*?)(?:$|;)")]
- private static partial Regex DatabaseNamePattern();
-
- [GeneratedRegex(@"(?:^|;)User=(.*?)(?:$|;)")]
- private static partial Regex UsernamePattern();
+ Connection = new NpgsqlConnection(EnvSettings.DatabaseConnection);
+ Connection.Open();
}
+
+ ~Pf2eDatabase()
+ {
+ Connection.Close();
+ }
+
+ public static Pf2eDatabase Instance { get; } = new();
+
+ public NpgsqlTransaction? Transaction { get; private set; }
+
+ public void StartTransaction()
+ {
+ if (Transaction != null)
+ {
+ throw new InvalidOperationException("Transaction already started.");
+ }
+
+ Transaction = Connection.BeginTransaction();
+ }
+
+ public void Commit()
+ {
+ if (Transaction == null)
+ {
+ throw new InvalidOperationException("No transaction started.");
+ }
+
+ Transaction.Commit();
+ }
+
+ public void ExecuteCommand(string sql)
+ {
+ NpgsqlCommand command = GetCommand(sql);
+
+ command.ExecuteNonQuery();
+ }
+
+ public NpgsqlCommand GetCommand(string sql)
+ {
+ return new NpgsqlCommand(sql, Connection);
+ }
+
+
+
+
+ /*
+ public void RebuildDatabase()
+ {
+ // Закрываем текущее соединение
+ Connection.Close();
+
+ // Получение имён
+ var databaseNamePattern = DatabaseNamePattern();
+ var userConnection = databaseNamePattern.Replace(EnvSettings.DatabaseConnection, ";");
+ var databaseName = databaseNamePattern.Match(EnvSettings.DatabaseConnection).Groups[1].Value;
+ var username = UserNamePattern().Match(EnvSettings.DatabaseConnection).Groups[1].Value;
+
+ // Временное подключение к базе данных
+ NpgsqlConnection tmpConnection = new(userConnection);
+ tmpConnection.Open();
+
+ // Удаляем базу данных
+ NpgsqlCommand dropCommand = new($"DROP DATABASE \"{databaseName}\";", tmpConnection);
+ dropCommand.ExecuteNonQuery();
+
+ // Создаём новую базу данных
+ NpgsqlCommand createCommand = new($@"
+ CREATE DATABASE {databaseName}
+ WITH OWNER = {username}
+ ENCODING = 'UTF8'
+ CONNECTION LIMIT = -1;
+ ", tmpConnection);
+ createCommand.ExecuteNonQuery();
+
+ string[] permissionCommands = [
+ $"GRANT TEMPORARY, CONNECT ON DATABASE {databaseName} TO PUBLIC;",
+ $"GRANT ALL ON DATABASE {databaseName} TO {username} WITH GRANT OPTION;",
+ $"GRANT ALL ON DATABASE {databaseName} TO postgres;"
+ ];
+
+ foreach (var command in permissionCommands)
+ {
+ NpgsqlCommand permissionCommand = new(command, tmpConnection);
+ permissionCommand.ExecuteNonQuery();
+ }
+
+ // Закрываем временное соединение
+ tmpConnection.Close();
+
+ // Заново создаём соединение
+ Connection = new NpgsqlConnection(EnvSettings.DatabaseConnection);
+ }
+
+ */
+
+ [GeneratedRegex(@"(?:^|;)Database=(.*?)(?:$|;)")]
+ private static partial Regex DatabaseNamePattern();
+
+ [GeneratedRegex(@"(?:^|;)User=(.*?)(?:$|;)")]
+ private static partial Regex UsernamePattern();
}
diff --git a/Pf2eDataScrapper/Pf2eTestContext.cs b/Pf2eDataScrapper/Pf2eTestContext.cs
index 7f34c6c..b66930e 100644
--- a/Pf2eDataScrapper/Pf2eTestContext.cs
+++ b/Pf2eDataScrapper/Pf2eTestContext.cs
@@ -1,9 +1,7 @@
using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Pf2eDataScrapper.Model;
+using Pf2eDataScrapper.Model.Common;
using Pf2eDataScrapper.Model.Enum;
-using System.ComponentModel;
-using System.Reflection;
namespace Pf2eDataScrapper;
@@ -103,8 +101,10 @@ public partial class Pf2eTestContext : DbContext
public virtual DbSet Traits { get; set; }
#endregion
+
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
+ EnvSettings.Load();
optionsBuilder.UseNpgsql(EnvSettings.DatabaseConnection,
builder =>
{
@@ -115,50 +115,6 @@ public partial class Pf2eTestContext : DbContext
);
}
- protected string FromEnum(T enumValue) where T : Enum
- {
- var enumFieldName = enumValue.ToString();
- var field = typeof(T).GetField(enumFieldName);
- if (field is null)
- {
- return enumFieldName;
- }
-
- var attribute = field.GetCustomAttribute();
- return attribute is null ? enumFieldName : attribute.Description;
- }
-
- protected T ToEnum(string enumValue) where T : Enum
- {
- var enumType = typeof(T);
- foreach (var field in enumType.GetFields())
- {
- var attribute = field.GetCustomAttribute();
- if (attribute is null)
- {
- if (field.Name == enumValue)
- {
- return (T)field.GetValue(null)!;
- }
- }
- else
- {
- if (attribute.Description == enumValue)
- {
- return (T)field.GetValue(null)!;
- }
- }
- }
- throw new ArgumentException($"No matching value found for {enumValue} in {enumType.Name}");
- }
-
- protected ValueConverter GetEnumConverter() where T : Enum
- {
- return new ValueConverter(
- v => FromEnum(v),
- v => ToEnum(v));
- }
-
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.UseIdentityByDefaultColumns();
@@ -198,8 +154,7 @@ public partial class Pf2eTestContext : DbContext
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.Description).HasColumnName("description");
entity.Property(e => e.DescriptionGm).HasColumnName("description_gm");
- entity.Property(e => e.Type)
- .HasColumnName("type");
+ entity.Property(e => e.Type).HasColumnName("type");
entity.Property(e => e.Img)
.HasMaxLength(150)
.HasColumnName("img");
diff --git a/Pf2eDataScrapper/Program.cs b/Pf2eDataScrapper/Program.cs
index 181a6d0..57a9bb7 100644
--- a/Pf2eDataScrapper/Program.cs
+++ b/Pf2eDataScrapper/Program.cs
@@ -1,10 +1,9 @@
using Pf2eDataScrapper;
using Pf2eDataScrapper.Importers.Implementations.Aonprd;
-using Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry;
EnvSettings.Load();
-var importer = new AonprdImporter();
+AonprdImporter importer = new AonprdImporter();
importer.Prepare();
importer.BuildSchemas();
diff --git a/Pf2eDataScrapper/SchemaBuilder/SchemaNode.cs b/Pf2eDataScrapper/SchemaBuilder/SchemaNode.cs
index 72fce6b..098f985 100644
--- a/Pf2eDataScrapper/SchemaBuilder/SchemaNode.cs
+++ b/Pf2eDataScrapper/SchemaBuilder/SchemaNode.cs
@@ -1,244 +1,243 @@
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.SchemaBuilder.Types;
-namespace Pf2eDataScrapper.SchemaBuilder
+namespace Pf2eDataScrapper.SchemaBuilder;
+
+///
+/// Элемент схемы данных.
+///
+internal class SchemaNode
{
///
- /// Элемент схемы данных.
+ /// Отображаемое имя элемента.
///
- internal class SchemaNode
+ public string Name = "";
+
+ ///
+ /// Путь к элементу.
+ ///
+ public string Path = "";
+
+ ///
+ /// Родительский элемент.
+ ///
+ public SchemaNode? Parent = null;
+
+ ///
+ /// Указание, является ли элемент корневым.
+ ///
+ public bool Root = false;
+
+ ///
+ /// Корневой элемент схемы данных.
+ ///
+ public SchemaNode RootNode => Root ? this : Parent!.RootNode;
+
+ ///
+ /// Типы данных, использующиеся в элементе.
+ ///
+ public List Types = [];
+
+ ///
+ /// Указание, может ли этот элемент отсутсвовать в структуре данных.
+ ///
+ public bool IsNullable = false;
+
+ ///
+ /// Объект для определения типа поля в схеме данных.
+ ///
+ public TypeResolver Resolver = new();
+
+ ///
+ /// Количество значений, добавленных в тип.
+ ///
+ public int Values { get; protected set; } = 0;
+
+ ///
+ /// Указание, является ли тип элемента простым.
+ ///
+ public bool IsSimple => Types.Count == 1;
+
+ ///
+ /// Конструктор корневого элемента.
+ ///
+ public SchemaNode()
{
- ///
- /// Отображаемое имя элемента.
- ///
- public string Name = "";
+ this.Root = true;
+ }
- ///
- /// Путь к элементу.
- ///
- public string Path = "";
+ ///
+ /// Конструктор элемента схемы данных.
+ ///
+ /// Родительский элемент.
+ /// Имя элемента.
+ public SchemaNode(SchemaNode parent, string name)
+ {
+ this.Parent = parent;
+ this.Name = name;
+ this.Path = parent.Path + "." + name;
+ this.Resolver = parent.Resolver;
+ }
- ///
- /// Родительский элемент.
- ///
- public SchemaNode? Parent = null;
-
- ///
- /// Указание, является ли элемент корневым.
- ///
- public bool Root = false;
-
- ///
- /// Корневой элемент схемы данных.
- ///
- public SchemaNode RootNode => Root ? this : Parent!.RootNode;
-
- ///
- /// Типы данных, использующиеся в элементе.
- ///
- public List Types = [];
-
- ///
- /// Указание, может ли этот элемент отсутсвовать в структуре данных.
- ///
- public bool IsNullable = false;
-
- ///
- /// Объект для определения типа поля в схеме данных.
- ///
- public TypeResolver Resolver = new();
-
- ///
- /// Количество значений, добавленных в тип.
- ///
- public int Values { get; protected set; } = 0;
-
- ///
- /// Указание, является ли тип элемента простым.
- ///
- public bool IsSimple => Types.Count == 1;
-
- ///
- /// Конструктор корневого элемента.
- ///
- public SchemaNode()
+ ///
+ /// Добавление нового возможного значения.
+ ///
+ /// Добавляемое значение
+ public void AddValue(JToken? value)
+ {
+ if (value is null || Resolver.TokenType(value) == JTokenType.Null)
{
- this.Root = true;
+ IsNullable = true;
+ return;
}
- ///
- /// Конструктор элемента схемы данных.
- ///
- /// Родительский элемент.
- /// Имя элемента.
- public SchemaNode(SchemaNode parent, string name)
- {
- this.Parent = parent;
- this.Name = name;
- this.Path = parent.Path + "." + name;
- this.Resolver = parent.Resolver;
- }
+ Values++;
- ///
- /// Добавление нового возможного значения.
- ///
- /// Добавляемое значение
- public void AddValue(JToken? value)
+ foreach (AbstractSchemaType type in Types)
{
- if (value is null || Resolver.TokenType(value) == JTokenType.Null)
+ if (type.IsCompatibleValue(value))
{
- IsNullable = true;
+ type.AddValue(value);
return;
}
-
- Values++;
-
- foreach (var type in Types)
- {
- if (type.IsCompatibleValue(value))
- {
- type.AddValue(value);
- return;
- }
- }
-
- var newType = Resolver.Resolve(this, value);
-
- if (newType.IsCompatibleValue(value))
- {
- Types.Add(newType);
- newType.AddValue(value);
- }
- else
- {
- var fallbackType = Resolver.Resolve(this, value, true);
- Types.Add(fallbackType);
- fallbackType.AddValue(value);
- }
}
- ///
- /// Получение строкового представоения типа элемента.
- ///
- /// Строковое представоение типа элемента
- public string GetTypeName()
+ AbstractSchemaType newType = Resolver.Resolve(this, value);
+
+ if (newType.IsCompatibleValue(value))
{
- if (IsSimple)
- {
- return Types[0].GetTypeName();
- }
-
- var typeNames = Types.Select(t => t.GetTypeName()).ToList();
-
- return string.Join(" | ", typeNames);
+ Types.Add(newType);
+ newType.AddValue(value);
}
-
- ///
- /// Полное строковое представление элемента.
- ///
- /// Строковое представление элемента.
- public override string ToString()
+ else
{
- var result = new Dictionary()
- {
- ["type"] = GetTypeName(),
- ["path"] = Path,
- ["is_null"] = IsNullable ? "true" : "false",
- ["values"] = Values.ToString()
- };
-
- if (IsSimple)
- {
- return FormatYaml(result, Types[0].GetYamlData());
- }
-
- if (Types.Count == 0)
- {
- return FormatYaml(result, new() { ["is_empty"] = "true" });
- }
-
- List types = [];
-
- foreach (var type in Types)
- {
- types.Add(Indent(type?.ToString() ?? ""));
- }
-
- return FormatYaml(result, new() { ["types"] = "- " + string.Join("\r\n- ", types) });
- }
-
- ///
- /// Подготовка элемента к красивому представлению.
- ///
- public void Beautify()
- {
- foreach (var type in Types)
- {
- type.Beautify();
- }
- }
-
-
-
- ///
- /// Отступ для строкового представления.
- ///
- public const string Tab = " ";
-
- ///
- /// Предел количество отображаемых элементов.
- ///
- public const int ElementLimit = 20;
-
- ///
- /// Увеличение отступа строки.
- ///
- /// Изменяемая строка.
- /// Строка с добавленными отступами.
- 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;
+ AbstractSchemaType fallbackType = Resolver.Resolve(this, value, true);
+ Types.Add(fallbackType);
+ fallbackType.AddValue(value);
}
}
+
+ ///
+ /// Получение строкового представоения типа элемента.
+ ///
+ /// Строковое представоение типа элемента
+ public string GetTypeName()
+ {
+ if (IsSimple)
+ {
+ return Types[0].GetTypeName();
+ }
+
+ List typeNames = [.. Types.Select(t => t.GetTypeName())];
+
+ return string.Join(" | ", typeNames);
+ }
+
+ ///
+ /// Полное строковое представление элемента.
+ ///
+ /// Строковое представление элемента.
+ public override string ToString()
+ {
+ Dictionary result = new()
+ {
+ ["type"] = GetTypeName(),
+ ["path"] = Path,
+ ["is_null"] = IsNullable ? "true" : "false",
+ ["values"] = Values.ToString()
+ };
+
+ if (IsSimple)
+ {
+ return FormatYaml(result, Types[0].GetYamlData());
+ }
+
+ if (Types.Count == 0)
+ {
+ return FormatYaml(result, new() { ["is_empty"] = "true" });
+ }
+
+ List types = [];
+
+ foreach (AbstractSchemaType type in Types)
+ {
+ types.Add(Indent(type?.ToString() ?? ""));
+ }
+
+ return FormatYaml(result, new() { ["types"] = "- " + string.Join("\r\n- ", types) });
+ }
+
+ ///
+ /// Подготовка элемента к красивому представлению.
+ ///
+ public void Beautify()
+ {
+ foreach (AbstractSchemaType type in Types)
+ {
+ type.Beautify();
+ }
+ }
+
+
+
+ ///
+ /// Отступ для строкового представления.
+ ///
+ public const string Tab = " ";
+
+ ///
+ /// Предел количество отображаемых элементов.
+ ///
+ public const int ElementLimit = 20;
+
+ ///
+ /// Увеличение отступа строки.
+ ///
+ /// Изменяемая строка.
+ /// Строка с добавленными отступами.
+ public static string Indent(string text)
+ {
+ return text.Replace("\r\n", "\r\n" + Tab);
+ }
+
+ ///
+ /// Форматирование данных в YAML.
+ ///
+ /// Словарь данных.
+ /// Строка форматированных данных
+ public static string FormatYaml(params List> input)
+ {
+ string result = "";
+
+ foreach (KeyValuePair kvp in MergeDictionaries(input))
+ {
+ string 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)
+ {
+ Dictionary result = [];
+
+ foreach (Dictionary item in input)
+ {
+ foreach (KeyValuePair 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/TypeResolver.cs b/Pf2eDataScrapper/SchemaBuilder/TypeResolver.cs
index 4ed3eb5..7b3b1e9 100644
--- a/Pf2eDataScrapper/SchemaBuilder/TypeResolver.cs
+++ b/Pf2eDataScrapper/SchemaBuilder/TypeResolver.cs
@@ -1,125 +1,111 @@
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.SchemaBuilder.Types;
-namespace Pf2eDataScrapper.SchemaBuilder
+namespace Pf2eDataScrapper.SchemaBuilder;
+
+///
+/// Класс для определения типа поля в схеме данных.
+///
+internal class TypeResolver
{
///
- /// Класс для определения типа поля в схеме данных.
+ /// Проверка соответствия пути.
///
- internal class TypeResolver
+ /// Элемент, путь которого проверяется.
+ /// Проверяемый путь. Допускается использование `*` в местах, где допускается любое значение.
+ /// `true`, если `node.Path` соответсвует указанному в `path` значению.
+ public bool CheckPath(SchemaNode node, string path)
{
- ///
- /// Проверка соответствия пути.
- ///
- /// Элемент, путь которого проверяется.
- /// Проверяемый путь. Допускается использование `*` в местах, где допускается любое значение.
- /// `true`, если `node.Path` соответсвует указанному в `path` значению.
- public bool CheckPath(SchemaNode node, string path)
+ if (!path.Contains("*"))
{
- if (!path.Contains("*"))
- {
- return path == node.Path;
- }
-
- var pathParts = path.Split('.');
- var nodeParts = node.Path.Split('.');
-
- if (pathParts.Length > nodeParts.Length)
- {
- return false;
- }
-
- return !pathParts.Where((t, i) => t != "*" && t != nodeParts[i]).Any();
+ return path == node.Path;
}
- ///
- /// Проверка соответствия пути.
- ///
- /// Элемент, путь которого проверяется.
- /// Проверяемые пути. Допускается использование `*` в местах, где допускается любое значение.
- /// `true`, если `node.Path` соответсвует хотя бы одному указанному в `paths` значению.
- public bool CheckPath(SchemaNode node, ICollection paths)
+ string[] pathParts = path.Split('.');
+ string[] nodeParts = node.Path.Split('.');
+
+ return pathParts.Length > nodeParts.Length ? false : !pathParts.Where((t, i) => t != "*" && t != nodeParts[i]).Any();
+ }
+
+ ///
+ /// Проверка соответствия пути.
+ ///
+ /// Элемент, путь которого проверяется.
+ /// Проверяемые пути. Допускается использование `*` в местах, где допускается любое значение.
+ /// `true`, если `node.Path` соответсвует хотя бы одному указанному в `paths` значению.
+ public bool CheckPath(SchemaNode node, ICollection paths)
+ {
+ return paths.Any(path => CheckPath(node, path));
+ }
+
+ ///
+ /// Получение типа значения.
+ ///
+ /// Значение.
+ /// Типа значения.
+ public JTokenType TokenType(JToken? value)
+ {
+ return value is null || value.Type is JTokenType.Null or JTokenType.Undefined or JTokenType.None ? JTokenType.Null : value.Type;
+ }
+
+ ///
+ /// Частное определение типа поля.
+ ///
+ /// Поле схемы данных, для которого создаётся тип.
+ /// Добавляемое значение.
+ /// Новый тип для схемы данных. `null`, что бы использовать значение по умолчанию
+ protected virtual AbstractSchemaType? CustomResolve(SchemaNode node, JToken? value)
+ {
+ return null;
+ }
+
+ ///
+ /// Определение типа поля.
+ ///
+ /// Поле схемы данных, для которого создаётся тип.
+ /// Добавляемое значение.
+ /// Добавляемое значение.
+ /// Новый тип для схемы данных
+ ///
+ /// Возникает, если у `value` значение идентично `null`
+ /// (такие значения должны обрабаотываться в `SchemaNode`).
+ ///
+ public AbstractSchemaType Resolve(SchemaNode node, JToken? value, bool disableResolve)
+ {
+ if (!disableResolve)
{
- return paths.Any(path => CheckPath(node, path));
+ AbstractSchemaType? customType = this.CustomResolve(node, value);
+
+ if (customType is not null)
+ {
+ return customType;
+ }
}
- ///
- /// Получение типа значения.
- ///
- /// Значение.
- /// Типа значения.
- public JTokenType TokenType(JToken? value)
- {
- if (value is null || value.Type is JTokenType.Null or JTokenType.Undefined or JTokenType.None)
- {
- return JTokenType.Null;
- }
+ JTokenType type = TokenType(value);
- return value.Type;
- }
-
- ///
- /// Частное определение типа поля.
- ///
- /// Поле схемы данных, для которого создаётся тип.
- /// Добавляемое значение.
- /// Новый тип для схемы данных. `null`, что бы использовать значение по умолчанию
- protected virtual AbstractSchemaType? CustomResolve(SchemaNode node, JToken? value)
- {
- return null;
- }
-
- ///
- /// Определение типа поля.
- ///
- /// Поле схемы данных, для которого создаётся тип.
- /// Добавляемое значение.
- /// Добавляемое значение.
- /// Новый тип для схемы данных
- ///
- /// Возникает, если у `value` значение идентично `null`
- /// (такие значения должны обрабаотываться в `SchemaNode`).
- ///
- public AbstractSchemaType Resolve(SchemaNode node, JToken? value, bool disableResolve)
- {
- if (!disableResolve)
- {
- var customType = this.CustomResolve(node, value);
-
- if (customType is not null)
- {
- return customType;
- }
- }
-
- var type = TokenType(value);
-
- if (type == JTokenType.Null)
- {
- throw new ArgumentNullException(nameof(value));
- }
-
- return type switch
+ return type == JTokenType.Null
+ ? throw new ArgumentNullException(nameof(value))
+ : type switch
{
JTokenType.Array => new ArraySchemaType(node),
JTokenType.Object => new ObjectSchemaType(node),
_ => new StaticSchemaType(node, type)
};
- }
+ }
- ///
- /// Определение типа поля.
- ///
- /// Поле схемы данных, для которого создаётся тип.
- /// Добавляемое значение.
- /// Новый тип для схемы данных
- ///
- /// Возникает, если у `value` значение идентично `null`
- /// (такие значения должны обрабаотываться в `SchemaNode`).
- ///
- public AbstractSchemaType Resolve(SchemaNode node, JToken? value)
- {
- return this.Resolve(node, value, false);
- }
+ ///
+ /// Определение типа поля.
+ ///
+ /// Поле схемы данных, для которого создаётся тип.
+ /// Добавляемое значение.
+ /// Новый тип для схемы данных
+ ///
+ /// Возникает, если у `value` значение идентично `null`
+ /// (такие значения должны обрабаотываться в `SchemaNode`).
+ ///
+ public AbstractSchemaType Resolve(SchemaNode node, JToken? value)
+ {
+ return this.Resolve(node, value, false);
}
}
diff --git a/Pf2eDataScrapper/SchemaBuilder/Types/AbstractSchemaType.cs b/Pf2eDataScrapper/SchemaBuilder/Types/AbstractSchemaType.cs
index 425ca39..670c63f 100644
--- a/Pf2eDataScrapper/SchemaBuilder/Types/AbstractSchemaType.cs
+++ b/Pf2eDataScrapper/SchemaBuilder/Types/AbstractSchemaType.cs
@@ -1,65 +1,64 @@
using Newtonsoft.Json.Linq;
-namespace Pf2eDataScrapper.SchemaBuilder.Types
+namespace Pf2eDataScrapper.SchemaBuilder.Types;
+
+///
+/// Абстрактный тип представоления данных в схеме.
+///
+/// Элемент, к которому добавляется тип.
+internal abstract class AbstractSchemaType(SchemaNode parent)
{
///
- /// Абстрактный тип представоления данных в схеме.
+ /// Элемент схемы данных, к которому относится тип.
///
- /// Элемент, к которому добавляется тип.
- internal abstract class AbstractSchemaType(SchemaNode parent)
+ public SchemaNode Parent = parent;
+
+ ///
+ /// Корневой элемент схемы данных.
+ ///
+ public SchemaNode Root => Parent.RootNode;
+
+ ///
+ /// Объект для определения типа поля в схеме данных.
+ ///
+ public TypeResolver Resolver => Root.Resolver;
+
+ ///
+ /// Проверка, что значение совместимо с текущим типом.
+ ///
+ /// Проверяемое значение.
+ /// `true`, если значение совместимо с текущим типом.
+ public abstract bool IsCompatibleValue(JToken value);
+
+ ///
+ /// Добавление нового значения.
+ ///
+ /// Новое значение.
+ public abstract void AddValue(JToken value);
+
+ ///
+ /// Подготовка типа к красивому представлению.
+ ///
+ public abstract void Beautify();
+
+ ///
+ /// Получение строкового представоения типа элемента.
+ ///
+ /// Строковое представоение типа элемента
+ public abstract string GetTypeName();
+
+ ///
+ /// Получение данных для форматирования в YAML.
+ ///
+ /// Словарь данных
+ public abstract Dictionary GetYamlData();
+
+ ///
+ /// Полное строковое представление элемента.
+ ///
+ /// Строковое представление элемента.
+ public override string ToString()
{
- ///
- /// Элемент схемы данных, к которому относится тип.
- ///
- public SchemaNode Parent = parent;
-
- ///
- /// Корневой элемент схемы данных.
- ///
- public SchemaNode Root => Parent.RootNode;
-
- ///
- /// Объект для определения типа поля в схеме данных.
- ///
- public TypeResolver Resolver => Root.Resolver;
-
- ///
- /// Проверка, что значение совместимо с текущим типом.
- ///
- /// Проверяемое значение.
- /// `true`, если значение совместимо с текущим типом.
- public abstract bool IsCompatibleValue(JToken value);
-
- ///
- /// Добавление нового значения.
- ///
- /// Новое значение.
- public abstract void AddValue(JToken value);
-
- ///
- /// Подготовка типа к красивому представлению.
- ///
- public abstract void Beautify();
-
- ///
- /// Получение строкового представоения типа элемента.
- ///
- /// Строковое представоение типа элемента
- public abstract string GetTypeName();
-
- ///
- /// Получение данных для форматирования в YAML.
- ///
- /// Словарь данных
- public abstract Dictionary GetYamlData();
-
- ///
- /// Полное строковое представление элемента.
- ///
- /// Строковое представление элемента.
- public override string ToString()
- {
- return SchemaNode.FormatYaml(GetYamlData());
- }
+ 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 3f66376..1383c5a 100644
--- a/Pf2eDataScrapper/SchemaBuilder/Types/ArraySchemaType.cs
+++ b/Pf2eDataScrapper/SchemaBuilder/Types/ArraySchemaType.cs
@@ -1,89 +1,88 @@
using Newtonsoft.Json.Linq;
-namespace Pf2eDataScrapper.SchemaBuilder.Types
+namespace Pf2eDataScrapper.SchemaBuilder.Types;
+
+///
+/// Тип представоления массива в схеме.
+///
+/// Элемент, к которому добавляется тип.
+internal class ArraySchemaType(SchemaNode parent) : AbstractSchemaType(parent)
{
///
- /// Тип представоления массива в схеме.
+ /// Минимальное количество элементов в массиве.
///
- /// Элемент, к которому добавляется тип.
- internal class ArraySchemaType(SchemaNode parent) : AbstractSchemaType(parent)
+ public int MinCount = int.MaxValue;
+
+ ///
+ /// Максимальное количество элементов в массиве.
+ ///
+ public int MaxCount = int.MinValue;
+
+ ///
+ /// Схема элемента массива.
+ ///
+ protected SchemaNode ElementSchema = new(parent, "[]");
+
+ ///
+ /// Проверка, что значение совместимо с текущим типом.
+ ///
+ /// Проверяемое значение.
+ /// `true`, если значение совместимо с текущим типом.
+ public override bool IsCompatibleValue(JToken value)
{
- ///
- /// Минимальное количество элементов в массиве.
- ///
- public int MinCount = int.MaxValue;
+ return Resolver.TokenType(value) == JTokenType.Array;
+ }
- ///
- /// Максимальное количество элементов в массиве.
- ///
- public int MaxCount = int.MinValue;
-
- ///
- /// Схема элемента массива.
- ///
- protected SchemaNode ElementSchema = new(parent, "[]");
-
- ///
- /// Проверка, что значение совместимо с текущим типом.
- ///
- /// Проверяемое значение.
- /// `true`, если значение совместимо с текущим типом.
- public override bool IsCompatibleValue(JToken value)
+ ///
+ /// Добавление нового значения.
+ ///
+ /// Новое значение.
+ public override void AddValue(JToken value)
+ {
+ if (value.Type != JTokenType.Array)
{
- return Resolver.TokenType(value) == JTokenType.Array;
+ throw new Exception("Value is not an array, did you forget to call IsCompatibleValue?");
}
- ///
- /// Добавление нового значения.
- ///
- /// Новое значение.
- public override void AddValue(JToken value)
+ JArray array = (JArray) value;
+
+ MinCount = Math.Min(MinCount, array.Count);
+ MaxCount = Math.Max(MaxCount, array.Count);
+
+ foreach (JToken item in array)
{
- if (value.Type != JTokenType.Array)
- {
- throw new Exception("Value is not an array, did you forget to call IsCompatibleValue?");
- }
-
- var array = (JArray)value;
-
- MinCount = Math.Min(MinCount, array.Count);
- MaxCount = Math.Max(MaxCount, array.Count);
-
- foreach (var item in array)
- {
- ElementSchema.AddValue(item);
- }
- }
-
- ///
- /// Подготовка типа к красивому представлению.
- ///
- public override void Beautify()
- {
- ElementSchema.Beautify();
- }
-
- ///
- /// Получение строкового представоения типа элемента.
- ///
- /// Строковое представоение типа элемента
- public override string GetTypeName()
- {
- return $"array<{ElementSchema.GetTypeName()}>";
- }
-
- ///
- /// Получение данных для форматирования в YAML.
- ///
- /// Словарь данных
- public override Dictionary GetYamlData()
- {
- return new()
- {
- ["min_count"] = MinCount.ToString(),
- ["max_count"] = MaxCount.ToString(),
- ["value_type"] = ElementSchema.ToString()
- };
+ ElementSchema.AddValue(item);
}
}
+
+ ///
+ /// Подготовка типа к красивому представлению.
+ ///
+ public override void Beautify()
+ {
+ ElementSchema.Beautify();
+ }
+
+ ///
+ /// Получение строкового представоения типа элемента.
+ ///
+ /// Строковое представоение типа элемента
+ public override string GetTypeName()
+ {
+ return $"array<{ElementSchema.GetTypeName()}>";
+ }
+
+ ///
+ /// Получение данных для форматирования в YAML.
+ ///
+ /// Словарь данных
+ public override Dictionary GetYamlData()
+ {
+ 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 3c76338..ac3d0a5 100644
--- a/Pf2eDataScrapper/SchemaBuilder/Types/DictionarySchemaType.cs
+++ b/Pf2eDataScrapper/SchemaBuilder/Types/DictionarySchemaType.cs
@@ -1,77 +1,76 @@
using Newtonsoft.Json.Linq;
-namespace Pf2eDataScrapper.SchemaBuilder.Types
+namespace Pf2eDataScrapper.SchemaBuilder.Types;
+
+///
+/// Тип представоления словаря в схеме.
+///
+/// Элемент, к которому добавляется тип.
+internal class DictionarySchemaType(SchemaNode parent) : AbstractSchemaType(parent)
{
///
- /// Тип представоления словаря в схеме.
+ /// Схема ключей словаря.
///
- /// Элемент, к которому добавляется тип.
- internal class DictionarySchemaType(SchemaNode parent) : AbstractSchemaType(parent)
+ public SchemaNode KeyNode = new(parent, "[key]");
+
+ ///
+ /// Схема значений словаря.
+ ///
+ public SchemaNode ItemNode = new(parent, "[value]");
+
+ ///
+ /// Проверка, что значение совместимо с текущим типом.
+ ///
+ /// Проверяемое значение.
+ /// `true`, если значение совместимо с текущим типом.
+ public override bool IsCompatibleValue(JToken value)
{
- ///
- /// Схема ключей словаря.
- ///
- public SchemaNode KeyNode = new(parent, "[key]");
+ return Resolver.TokenType(value) == JTokenType.Object;
+ }
- ///
- /// Схема значений словаря.
- ///
- public SchemaNode ItemNode = new(parent, "[value]");
+ ///
+ /// Добавление нового значения.
+ ///
+ /// Новое значение.
+ public override void AddValue(JToken value)
+ {
+ JObject obj = (JObject) value;
- ///
- /// Проверка, что значение совместимо с текущим типом.
- ///
- /// Проверяемое значение.
- /// `true`, если значение совместимо с текущим типом.
- public override bool IsCompatibleValue(JToken value)
+ foreach (KeyValuePair pair in obj)
{
- return Resolver.TokenType(value) == JTokenType.Object;
- }
-
- ///
- /// Добавление нового значения.
- ///
- /// Новое значение.
- public override void AddValue(JToken value)
- {
- var obj = (JObject)value;
-
- foreach (var pair in obj)
- {
- KeyNode.AddValue(pair.Key);
- ItemNode.AddValue(pair.Value);
- }
- }
-
- ///
- /// Подготовка типа к красивому представлению.
- ///
- public override void Beautify()
- {
- KeyNode.Beautify();
- ItemNode.Beautify();
- }
-
- ///
- /// Получение строкового представоения типа элемента.
- ///
- /// Строковое представоение типа элемента
- public override string GetTypeName()
- {
- return $"dict<{KeyNode.GetTypeName()}, {ItemNode.GetTypeName()}>";
- }
-
- ///
- /// Получение данных для форматирования в YAML.
- ///
- /// Словарь данных
- public override Dictionary GetYamlData()
- {
- return new Dictionary()
- {
- ["_key"] = KeyNode.ToString(),
- ["_value"] = ItemNode.ToString()
- };
+ KeyNode.AddValue(pair.Key);
+ ItemNode.AddValue(pair.Value);
}
}
+
+ ///
+ /// Подготовка типа к красивому представлению.
+ ///
+ public override void Beautify()
+ {
+ KeyNode.Beautify();
+ ItemNode.Beautify();
+ }
+
+ ///
+ /// Получение строкового представоения типа элемента.
+ ///
+ /// Строковое представоение типа элемента
+ public override string GetTypeName()
+ {
+ return $"dict<{KeyNode.GetTypeName()}, {ItemNode.GetTypeName()}>";
+ }
+
+ ///
+ /// Получение данных для форматирования в YAML.
+ ///
+ /// Словарь данных
+ public override Dictionary GetYamlData()
+ {
+ return new Dictionary()
+ {
+ ["_key"] = KeyNode.ToString(),
+ ["_value"] = ItemNode.ToString()
+ };
+ }
}
diff --git a/Pf2eDataScrapper/SchemaBuilder/Types/IgnoreSchemaType.cs b/Pf2eDataScrapper/SchemaBuilder/Types/IgnoreSchemaType.cs
index df025cd..c007c53 100644
--- a/Pf2eDataScrapper/SchemaBuilder/Types/IgnoreSchemaType.cs
+++ b/Pf2eDataScrapper/SchemaBuilder/Types/IgnoreSchemaType.cs
@@ -1,55 +1,54 @@
using Newtonsoft.Json.Linq;
-namespace Pf2eDataScrapper.SchemaBuilder.Types
+namespace Pf2eDataScrapper.SchemaBuilder.Types;
+
+///
+/// Тип, указывающий, что данные игнорируются.
+///
+/// Элемент, к которому добавляется тип.
+internal class IgnoreSchemaType(SchemaNode parent) : AbstractSchemaType(parent)
{
///
- /// Тип, указывающий, что данные игнорируются.
+ /// Проверка, что значение совместимо с текущим типом.
///
- /// Элемент, к которому добавляется тип.
- internal class IgnoreSchemaType(SchemaNode parent) : AbstractSchemaType(parent)
+ /// Проверяемое значение.
+ /// `true`, если значение совместимо с текущим типом.
+ public override bool IsCompatibleValue(JToken value)
{
- ///
- /// Проверка, что значение совместимо с текущим типом.
- ///
- /// Проверяемое значение.
- /// `true`, если значение совместимо с текущим типом.
- public override bool IsCompatibleValue(JToken value)
- {
- return true;
- }
+ return true;
+ }
- ///
- /// Добавление нового значения.
- ///
- /// Новое значение.
- public override void AddValue(JToken value)
- {
- }
+ ///
+ /// Добавление нового значения.
+ ///
+ /// Новое значение.
+ public override void AddValue(JToken value)
+ {
+ }
- ///
- /// Подготовка типа к красивому представлению.
- ///
- public override void Beautify()
- {
- }
+ ///
+ /// Подготовка типа к красивому представлению.
+ ///
+ public override void Beautify()
+ {
+ }
- ///
- /// Получение строкового представоения типа элемента.
- ///
- /// Строковое представоение типа элемента
- public override string GetTypeName()
- {
- return "ignore";
- }
+ ///
+ /// Получение строкового представоения типа элемента.
+ ///
+ /// Строковое представоение типа элемента
+ public override string GetTypeName()
+ {
+ return "ignore";
+ }
- ///
- /// Получение данных для форматирования в YAML.
- ///
- /// Словарь данных
- public override Dictionary GetYamlData()
- {
- return [];
- }
+ ///
+ /// Получение данных для форматирования в YAML.
+ ///
+ /// Словарь данных
+ public override Dictionary GetYamlData()
+ {
+ return [];
}
}
diff --git a/Pf2eDataScrapper/SchemaBuilder/Types/ObjectSchemaType.cs b/Pf2eDataScrapper/SchemaBuilder/Types/ObjectSchemaType.cs
index 5ff46ec..31db02e 100644
--- a/Pf2eDataScrapper/SchemaBuilder/Types/ObjectSchemaType.cs
+++ b/Pf2eDataScrapper/SchemaBuilder/Types/ObjectSchemaType.cs
@@ -1,124 +1,110 @@
using Newtonsoft.Json.Linq;
-namespace Pf2eDataScrapper.SchemaBuilder.Types
+namespace Pf2eDataScrapper.SchemaBuilder.Types;
+
+///
+/// Тип представоления объектов в схеме.
+///
+/// Элемент, к которому добавляется тип.
+internal class ObjectSchemaType(SchemaNode parent) : AbstractSchemaType(parent)
{
///
- /// Тип представоления объектов в схеме.
+ /// Элемнты полей объекта.
///
- /// Элемент, к которому добавляется тип.
- internal class ObjectSchemaType(SchemaNode parent) : AbstractSchemaType(parent)
+ public List Fields = [];
+
+ ///
+ /// Проверка, что значение совместимо с текущим типом.
+ ///
+ /// Проверяемое значение.
+ /// `true`, если значение совместимо с текущим типом.
+ public override bool IsCompatibleValue(JToken value)
{
- ///
- /// Элемнты полей объекта.
- ///
- public List Fields = [];
+ return Resolver.TokenType(value) == JTokenType.Object;
+ }
- ///
- /// Проверка, что значение совместимо с текущим типом.
- ///
- /// Проверяемое значение.
- /// `true`, если значение совместимо с текущим типом.
- public override bool IsCompatibleValue(JToken value)
+ ///
+ /// Добавление нового значения.
+ ///
+ /// Новое значение.
+ public override void AddValue(JToken value)
+ {
+ JObject obj = (JObject) value;
+
+ foreach (SchemaNode field in Fields)
{
- return Resolver.TokenType(value) == JTokenType.Object;
- }
-
- ///
- /// Добавление нового значения.
- ///
- /// Новое значение.
- public override void AddValue(JToken value)
- {
- var obj = (JObject)value;
-
- foreach (var field in Fields)
+ if (!obj.ContainsKey(field.Name))
{
- if (!obj.ContainsKey(field.Name))
- {
- field.IsNullable = true;
- }
- }
-
- foreach (var pair in obj)
- {
- var field = Fields.FirstOrDefault(f => f.Name == pair.Key);
-
- if (field is null)
- {
- field = new SchemaNode(Parent, pair.Key);
- Fields.Add(field);
- }
-
- field.AddValue(pair.Value);
+ field.IsNullable = true;
}
}
- ///
- /// Подготовка типа к красивому представлению.
- ///
- public override void Beautify()
+ foreach (KeyValuePair pair in obj)
{
- Fields.Sort((a, b) =>
+ SchemaNode? field = Fields.FirstOrDefault(f => f.Name == pair.Key);
+
+ if (field is null)
{
- if (a.IsNullable && !b.IsNullable)
- {
- return 0;
- }
-
- return string.Compare(a.Name, b.Name, StringComparison.Ordinal);
- });
-
- foreach (var field in Fields)
- {
- field.Beautify();
- }
- }
-
- ///
- /// Получение строкового представоения типа элемента.
- ///
- /// Строковое представоение типа элемента
- public override string GetTypeName()
- {
- return "object";
- }
-
- ///
- /// Получение данных для форматирования структуры в YAML.
- ///
- /// Словарь данных
- public Dictionary GetSchemaYaml()
- {
- var result = new Dictionary();
-
- foreach (var field in Fields)
- {
- var s = field.Name;
- if (field.IsNullable)
- {
- s = $"[{s}]";
- }
- else
- {
- s = $"'{s}'";
- }
- result.Add(s, field.ToString());
+ field = new SchemaNode(Parent, pair.Key);
+ Fields.Add(field);
}
- return result;
- }
-
- ///
- /// Получение данных для форматирования в YAML.
- ///
- /// Словарь данных
- public override Dictionary GetYamlData()
- {
- return new()
- {
- ["schema"] = SchemaNode.FormatYaml(GetSchemaYaml())
- };
+ field.AddValue(pair.Value);
}
}
+ ///
+ /// Подготовка типа к красивому представлению.
+ ///
+ public override void Beautify()
+ {
+ Fields.Sort((a, b) =>
+ {
+ return a.IsNullable && !b.IsNullable ? 0 : string.Compare(a.Name, b.Name, StringComparison.Ordinal);
+ });
+
+ foreach (SchemaNode field in Fields)
+ {
+ field.Beautify();
+ }
+ }
+
+ ///
+ /// Получение строкового представоения типа элемента.
+ ///
+ /// Строковое представоение типа элемента
+ public override string GetTypeName()
+ {
+ return "object";
+ }
+
+ ///
+ /// Получение данных для форматирования структуры в YAML.
+ ///
+ /// Словарь данных
+ public Dictionary GetSchemaYaml()
+ {
+ Dictionary result = new();
+
+ foreach (SchemaNode field in Fields)
+ {
+ string s = field.Name;
+ s = field.IsNullable ? $"[{s}]" : $"'{s}'";
+ result.Add(s, field.ToString());
+ }
+
+ 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 01df186..67b870c 100644
--- a/Pf2eDataScrapper/SchemaBuilder/Types/StaticSchemaType.cs
+++ b/Pf2eDataScrapper/SchemaBuilder/Types/StaticSchemaType.cs
@@ -1,102 +1,101 @@
using Newtonsoft.Json.Linq;
-namespace Pf2eDataScrapper.SchemaBuilder.Types
+namespace Pf2eDataScrapper.SchemaBuilder.Types;
+
+///
+/// Тип представоления простых значений в схеме.
+///
+/// Элемент, к которому добавляется тип.
+/// Тип значения.
+internal class StaticSchemaType(SchemaNode parent, JTokenType type) : AbstractSchemaType(parent)
{
///
- /// Тип представоления простых значений в схеме.
+ /// Тип значения.
///
- /// Элемент, к которому добавляется тип.
- /// Тип значения.
- internal class StaticSchemaType(SchemaNode parent, JTokenType type) : AbstractSchemaType(parent)
+ protected JTokenType Type = type;
+
+ ///
+ /// Набор возможных значений и их количества.
+ ///
+ protected Dictionary Values = [];
+
+ ///
+ /// Проверка, что значение совместимо с текущим типом.
+ ///
+ /// Проверяемое значение.
+ /// `true`, если значение совместимо с текущим типом.
+ public override bool IsCompatibleValue(JToken value)
{
- ///
- /// Тип значения.
- ///
- protected JTokenType Type = type;
+ return value.Type == Type;
+ }
- ///
- /// Набор возможных значений и их количества.
- ///
- protected Dictionary Values = [];
+ ///
+ /// Добавление нового значения.
+ ///
+ /// Новое значение.
+ public override void AddValue(JToken value)
+ {
+ Values.TryAdd(value, 0);
- ///
- /// Проверка, что значение совместимо с текущим типом.
- ///
- /// Проверяемое значение.
- /// `true`, если значение совместимо с текущим типом.
- public override bool IsCompatibleValue(JToken value)
+ Values[value]++;
+ }
+
+ ///
+ /// Подготовка типа к красивому представлению.
+ ///
+ public override void Beautify()
+ {
+ if (Type == JTokenType.String)
{
- return value.Type == Type;
- }
+ Dictionary newValues = new();
- ///
- /// Добавление нового значения.
- ///
- /// Новое значение.
- public override void AddValue(JToken value)
- {
- Values.TryAdd(value, 0);
-
- Values[value]++;
- }
-
- ///
- /// Подготовка типа к красивому представлению.
- ///
- public override void Beautify()
- {
- if (Type == JTokenType.String)
+ foreach (KeyValuePair pair in Values)
{
- var newValues = new Dictionary();
-
- foreach (var pair in Values)
- {
- var newValue = "\"" + pair.Key.ToString().Trim().Replace("\"", "\\\"") + "\"";
- newValues.TryAdd(newValue, 0);
- newValues[newValue] += pair.Value;
- }
-
- Values = newValues;
+ string newValue = "\"" + pair.Key.ToString().Trim().Replace("\"", "\\\"") + "\"";
+ newValues.TryAdd(newValue, 0);
+ newValues[newValue] += pair.Value;
}
- Values = Values.OrderByDescending(pair => pair.Value).ToDictionary(pair => pair.Key, pair => pair.Value);
+ Values = newValues;
}
- ///
- /// Получение строкового представоения типа элемента.
- ///
- /// Строковое представоение типа элемента
- public override string GetTypeName()
+ Values = Values.OrderByDescending(pair => pair.Value).ToDictionary(pair => pair.Key, pair => pair.Value);
+ }
+
+ ///
+ /// Получение строкового представоения типа элемента.
+ ///
+ /// Строковое представоение типа элемента
+ public override string GetTypeName()
+ {
+ return Type.ToString().ToLower();
+ }
+
+ ///
+ /// Получение данных для форматирования в YAML.
+ ///
+ /// Словарь данных
+ public override Dictionary GetYamlData()
+ {
+ List values = [];
+ int count = Values.Count;
+
+ string prefix = (count == 1) ? "" : "- ";
+
+ if (count is <= SchemaNode.ElementLimit and > 0 && (Type != JTokenType.String || !Values.Any(s => s.ToString().Contains('\n'))))
{
- return Type.ToString().ToLower();
- }
-
- ///
- /// Получение данных для форматирования в YAML.
- ///
- /// Словарь данных
- public override Dictionary GetYamlData()
- {
- var values = new List();
- var count = Values.Count;
-
- var prefix = (count == 1) ? "" : "- ";
-
- if (count is <= SchemaNode.ElementLimit and > 0 && (Type != JTokenType.String || !Values.Any(s => s.ToString().Contains('\n'))))
+ foreach (KeyValuePair kvp in Values)
{
- foreach (var kvp in Values)
- {
- values.Add($"{prefix}{kvp.Key} (x{kvp.Value})");
- }
+ values.Add($"{prefix}{kvp.Key} (x{kvp.Value})");
}
-
- 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]"
- };
}
+
+ 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]"
+ };
}
}