From 34be3a5fc4e913790e13ba40345805a8e0b3aa0e Mon Sep 17 00:00:00 2001 From: Ilya Kozhemyakin Date: Thu, 22 May 2025 00:34:57 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A4=D0=B0=D0=B1=D1=80=D0=B8=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=B8=20=D1=80=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D0=BD=D0=B3=20=D0=B1=D0=BB=D0=BE=D0=BA=D0=B0=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=87=D0=B8=D0=BA=D0=BE=D0=B2,?= =?UTF-8?q?=20=D0=92=D1=8B=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D1=81=D0=BB=D0=BE=D0=B2=D0=B0=D1=80=D0=B5=D0=B9=20=D0=BD=D0=B0?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=BE=D0=B5=D0=BA=20=D0=B0=D0=B4=D0=B0=D0=BF?= =?UTF-8?q?=D1=82=D0=B0=D1=86=D0=B8=D0=B8=20=D0=B2=20=D0=BE=D1=82=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20=D1=84=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Pf2eDataScrapper/App/ProcessorAttribute.cs | 79 ----- Pf2eDataScrapper/App/ProcessorCollection.cs | 261 --------------- Pf2eDataScrapper/Helpers/EntityView.cs | 1 + Pf2eDataScrapper/Helpers/ProcessProgress.cs | 2 +- Pf2eDataScrapper/ImportApplication.cs | 5 +- .../Aonprd/Helpers/AonprdBuilderGlobals.cs | 127 +++----- .../Processors/AbstractEntityProcessor.cs | 16 +- .../Processors/AbstractSubclassProcessor.cs | 2 +- .../Processors/Common/ExternalProcessor.cs | 7 +- .../Processors/Common/SkillProcessor.cs | 5 +- .../Processors/Common/SourceProcessor.cs | 3 +- .../Finalization/LegacyRemasterProcessors.cs | 19 +- .../MissingLegacyRemasterProcessorFactory.cs | 88 ++++++ .../Preparation/CompendiumLoadProcessor.cs | 4 +- .../Preparation/RepositoryUpdateProcessor.cs | 6 +- .../Preparation/SchemaBuildProcessor.cs | 2 +- .../Subclasses/ApparitionProcessor.cs | 6 +- .../Processors/Types/ActionProcessor.cs | 9 +- .../Processors/Types/AncestryProcessor.cs | 3 +- .../Processors/Types/ArchetypeProcessor.cs | 5 +- .../Processors/Types/BackgroundProcessor.cs | 3 +- .../Aonprd/Processors/Types/ClassProcessor.cs | 3 +- .../Aonprd/Processors/Types/FeatProcessor.cs | 2 +- .../Processors/Types/LanguageProcessor.cs | 4 +- .../Processors/Types/RitualProcessor.cs | 2 +- .../Processors/Types/Rules/RuleProcessor.cs | 2 +- .../Types/Rules/RulesOrderProcessor.cs | 4 +- .../Types/Rules/RulesTocProcessor.cs | 7 +- .../Aonprd/Processors/Types/SpellProcessor.cs | 2 +- .../Aonprd/Processors/Types/TraitProcessor.cs | 4 +- .../Processors/Entities/ActionProcessor.cs | 3 +- .../Processors/Entities/ConditionProcessor.cs | 3 +- .../Processors/FoundryEnAbstractProcessor.cs | 1 + .../Preparation/CompendiumFolderProcessor.cs | 4 +- .../Preparation/CompendiumItemsProcessor.cs | 4 +- .../Preparation/RepositoryUpdateProcessor.cs | 6 +- .../Preparation/SchemaBuildProcessor.cs | 2 +- Pf2eDataScrapper/Pf2eDataScrapper.csproj | 3 + .../Attributes/AbstractProcessorAttribute.cs | 35 +++ .../Attributes/ProcessorAttribute.cs | 10 + .../ProcessorCollectionAttribute.cs | 22 ++ .../ProcessorDependenciesAttribute.cs | 17 + .../Attributes/ProcessorFactoryAttribute.cs | 11 + .../Attributes}/ProcessorGroupEnum.cs | 9 +- .../Collection/ProcessorCollection.cs | 296 ++++++++++++++++++ .../Processors/Collection/ProcessorRecord.cs | 57 ++++ .../AbstractInputProcessor.cs | 4 +- .../AbstractSimpleProcessor.cs} | 6 +- .../{ => Definitions}/IProcessor.cs | 2 +- .../Factory/AbstractProcessorFactory.cs | 29 ++ .../Factory/CompendiumProcessorFactory.cs | 71 +++++ .../Factory/SimpleProcessorFactory.cs | 24 ++ .../General/DatabaseTruncateProcessor.cs | 3 +- .../Processors/ProcessorExecutor.cs | 76 +---- .../Resources/ImportAdaptation.json | 82 +++++ .../AbstractSchemaBuildProcessor.cs | 2 +- .../Component/EntityListControl.xaml.cs | 29 +- .../WPF/EntityViewer/EntityForm.xaml.cs | 4 +- .../EntityViewStructure/StructureRow.cs | 4 - .../WPF/ProgressForm/ProgressForm.xaml.cs | 5 +- .../ProcessorCollectionControl.xaml.cs | 11 +- .../WPF/StartForm/StartForm.xaml.cs | 2 +- ...signer.cs => 20250521155437_1.Designer.cs} | 2 +- ...0250521102908_1.cs => 20250521155437_1.cs} | 0 64 files changed, 921 insertions(+), 601 deletions(-) delete mode 100644 Pf2eDataScrapper/App/ProcessorAttribute.cs delete mode 100644 Pf2eDataScrapper/App/ProcessorCollection.cs create mode 100644 Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Finalization/MissingLegacyRemasterProcessorFactory.cs create mode 100644 Pf2eDataScrapper/Processors/Attributes/AbstractProcessorAttribute.cs create mode 100644 Pf2eDataScrapper/Processors/Attributes/ProcessorAttribute.cs create mode 100644 Pf2eDataScrapper/Processors/Attributes/ProcessorCollectionAttribute.cs create mode 100644 Pf2eDataScrapper/Processors/Attributes/ProcessorDependenciesAttribute.cs create mode 100644 Pf2eDataScrapper/Processors/Attributes/ProcessorFactoryAttribute.cs rename Pf2eDataScrapper/{App => Processors/Attributes}/ProcessorGroupEnum.cs (89%) create mode 100644 Pf2eDataScrapper/Processors/Collection/ProcessorCollection.cs create mode 100644 Pf2eDataScrapper/Processors/Collection/ProcessorRecord.cs rename Pf2eDataScrapper/Processors/{ => Definitions}/AbstractInputProcessor.cs (91%) rename Pf2eDataScrapper/Processors/{AbstractProcessor.cs => Definitions/AbstractSimpleProcessor.cs} (82%) rename Pf2eDataScrapper/Processors/{ => Definitions}/IProcessor.cs (85%) create mode 100644 Pf2eDataScrapper/Processors/Factory/AbstractProcessorFactory.cs create mode 100644 Pf2eDataScrapper/Processors/Factory/CompendiumProcessorFactory.cs create mode 100644 Pf2eDataScrapper/Processors/Factory/SimpleProcessorFactory.cs create mode 100644 Pf2eDataScrapper/Resources/ImportAdaptation.json rename Pf2eModel/Migrations/{20250521102908_1.Designer.cs => 20250521155437_1.Designer.cs} (99%) rename Pf2eModel/Migrations/{20250521102908_1.cs => 20250521155437_1.cs} (100%) diff --git a/Pf2eDataScrapper/App/ProcessorAttribute.cs b/Pf2eDataScrapper/App/ProcessorAttribute.cs deleted file mode 100644 index 9cc8fc1..0000000 --- a/Pf2eDataScrapper/App/ProcessorAttribute.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Pf2eDataScrapper.App; - -/// -/// Общий аттрибут обработчика. -/// -/// Название обработчика. -[AttributeUsage(AttributeTargets.Class)] -public class ProcessorAttribute(string name) : Attribute -{ - /// - /// Название обработчика. - /// - public string Name { get; init; } = name; - - /// - /// Описание обработчика. - /// - public string Description { get; init; } = name; - - /// - /// Группа обработчиков, к которому относится обработчик. - /// - public ProcessorGroupEnum Group { get; init; } = ProcessorGroupEnum.General; - - /// - /// Процессор включён по умолчанию. - /// - public bool Active { get; init; } = true; - - /// - /// Разрешить выполнять процессов в параллельном режиме - /// - public bool Parallel { get; init; } = false; - - /// - /// Обработчик набора элементов - /// - public virtual bool Collection { get; } = false; -} - -/// -/// Аттрибут обработчика набор элементов. -/// -/// Название обработчика. -[AttributeUsage(AttributeTargets.Class)] -public class ProcessorCollectionAttribute(string name) : ProcessorAttribute(name) -{ - /// - /// Название типов, который обрабатывает этот оброботчик. - /// null - обработать все типы. - /// - public required string? InnerType { get; init; } - - /// - /// Тип используемого компендиума. - /// - public required ProcessorCompendiumEnum CompendiumType { get; init; } - - /// - /// Обработчик набора элементов. - /// - public override bool Collection { get; } = true; -} - -/// -/// Аттрибут зависимостей обработчика. -/// -/// Коллекция названий обработчиков, которые должны быть выполнены до этого оброботчика. -[AttributeUsage(AttributeTargets.Class)] -public class ProcessorDependenciesAttribute(string[] dependencies) : Attribute -{ - /// - /// Коллекция названий обработчиков, которые должны быть выполнены до этого оброботчика. - /// - public ICollection Dependencies { get; } = dependencies; -} diff --git a/Pf2eDataScrapper/App/ProcessorCollection.cs b/Pf2eDataScrapper/App/ProcessorCollection.cs deleted file mode 100644 index 57a5d71..0000000 --- a/Pf2eDataScrapper/App/ProcessorCollection.cs +++ /dev/null @@ -1,261 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Pf2eDataScrapper.Processors; - -namespace Pf2eDataScrapper.App; - -/// -/// Класс с коллекцией обработчиков. -/// -internal class ProcessorCollection -{ - /// - /// Коллекция всех доступных обработчиков. - /// - public ICollection AllItems { get; } = []; - - /// - /// Коллекция обработчиков, которые будут обрабатываться. - /// Для изменения необходимо использовать . - /// - public List Items { get; private set; } = []; - - /// - /// Обеспечение доступа к элементам обработчиков. - /// - /// - /// - public ProcessorCollectionItem this[string name] => AllItems.First(item => item.Name == name); - - /// - /// Конструктор класса . - /// - public ProcessorCollection() - { - Assembly assembly = Assembly.GetExecutingAssembly(); - - foreach (Type type in assembly.GetTypes()) - { - if (type.GetCustomAttributes(typeof(ProcessorAttribute), true).Length <= 0) - { - continue; - } - - AllItems.Add(CreateItem(type)); - } - - CheckDependencies(); - FilterProcessors([]); - } - - /// - /// Создание элемента коллекции обработчиков. - /// - /// Тип обработчика. - /// - private ProcessorCollectionItem CreateItem(Type type) - { - if (!type.IsAssignableTo(typeof(IProcessor))) - { - throw new( - $"'ProcessorAttribute' attribute should only be applied to children of 'IProcessor' class. '{type.FullName}' is not." - ); - } - - ProcessorAttribute processorAttribute = type.GetCustomAttribute()!; - ProcessorDependenciesAttribute? dependenciesAttribute = - type.GetCustomAttribute(); - - bool isCollection = processorAttribute.Collection; - - string? innerType = null; - ProcessorCompendiumEnum? compendium = null; - - if (processorAttribute.GetType() == typeof(ProcessorCollectionAttribute)) - { - ProcessorCollectionAttribute processorCollectionAttribute = - (ProcessorCollectionAttribute)processorAttribute; - - innerType = processorCollectionAttribute.InnerType; - compendium = processorCollectionAttribute.CompendiumType; - } - - return new() - { - Name = processorAttribute.Name, - Type = type, - Description = processorAttribute.Description, - Group = processorAttribute.Group, - Dependencies = dependenciesAttribute?.Dependencies ?? [], - IsCollection = isCollection, - InnerType = innerType, - Compendium = compendium, - Active = processorAttribute.Active, - Parallel = processorAttribute.Parallel, - }; - } - - /// - /// Проверка, что все зависимости всех обработчиков могут быть удовлетворены. - /// - private void CheckDependencies() - { - foreach (ProcessorCollectionItem item in Items) - { - foreach (string dependency in item.Dependencies) - { - if (Items.All(i => i.Name != dependency)) - { - throw new($"Dependency '{dependency}' for processor '{item.Name}' not found."); - } - } - } - } - - /// - /// Сортировать обработчики в соответсвии со всеми зависимостями. - /// - public void SortItems() - { - Items.ForEach(item => item.Priority = -1); - - Dictionary priorities = []; - - while (priorities.Count < Items.Count) - { - foreach (ProcessorCollectionItem item in Items) - { - if (item.Priority >= 0) - { - continue; - } - - IEnumerable dependencyPriorities = item.Dependencies.Select(d => - priorities.GetValueOrDefault(d, -1) - ); - - if (dependencyPriorities.Any(p => p == -1)) - { - continue; - } - - item.Priority = Math.Max( - dependencyPriorities.Any() ? dependencyPriorities.Max() + 1 : 1, - (int)item.Group * 100 - ); - priorities.Add(item.Name, item.Priority); - } - } - - Items.Sort((a, b) => a.Priority - b.Priority); - } - - /// - /// Ограничить список используемых обработчиков по названию. - /// Автоматически включает все обработчики, от которых зависят указанные в аргументе обработчики. - /// - /// Коллекция названиий требуемых обработчиков. - public void FilterProcessors(ICollection processorNames) - { - if (processorNames.Count == 0) - { - Items = [.. AllItems]; - SortItems(); - return; - } - - Dictionary nameFlags = processorNames.ToDictionary(name => name, _ => false); - - while (nameFlags.Values.Any(v => !v)) - { - foreach ( - KeyValuePair pair in nameFlags.Where(pair => !pair.Value).ToList() - ) - { - ProcessorCollectionItem item = AllItems.First(item => item.Name == pair.Key); - - foreach (string dependency in item.Dependencies) - { - nameFlags.TryAdd(dependency, false); - } - - nameFlags[pair.Key] = true; - } - } - - Items = AllItems.Where(item => nameFlags.ContainsKey(item.Name)).ToList(); - } - - /// - /// Получить список типов, которые обрабатываются в компендиуме. - /// - /// Тип компендиума. - /// Набор типов. - public ICollection GetTypesOfCompendium(ProcessorCompendiumEnum compendium) => - Items.Select(item => item.InnerType).OfType().ToList(); -} - -/// -/// Элемент коллекции обработчиков. -/// -internal class ProcessorCollectionItem -{ - /// - /// Название обработчика. - /// - public required string Name { get; init; } - - /// - /// Тип класса обработчика. - /// - public required Type Type { get; init; } - - /// - /// Описание обработчика. - /// - public string Description { get; init; } = ""; - - /// - /// Группа обработчика. - /// - public required ProcessorGroupEnum Group { get; init; } - - /// - /// Коллекция названий обработчиков, после которых должен выполняться обработчик. - /// - public ICollection Dependencies { get; init; } = []; - - /// - /// Процессор включён по умолчанию. - /// - public bool Active { get; init; } = true; - - /// - /// Приоритет выполнения обработчика. - /// - public int Priority { get; set; } = -1; - - /// - /// Флаг, указывающий, обрабатывает ли обработчик коллекцию элементов. - /// Внутренний тип элементов указывается в . - /// - public required bool IsCollection { get; init; } - - /// - /// Флаг, указывающий внутренний тип коллекции обрабатываемых элементов. - /// - public string? InnerType { get; init; } - - /// - /// Название типов, который обрабатывает этот оброботчик. - /// null - обработать все типы. - /// - public ProcessorCompendiumEnum? Compendium { get; init; } - - /// - /// Разрешить выполнять процессов в параллельном режиме - /// - public bool Parallel { get; init; } = true; -} diff --git a/Pf2eDataScrapper/Helpers/EntityView.cs b/Pf2eDataScrapper/Helpers/EntityView.cs index 59c2b2b..a24964b 100644 --- a/Pf2eDataScrapper/Helpers/EntityView.cs +++ b/Pf2eDataScrapper/Helpers/EntityView.cs @@ -91,6 +91,7 @@ public class EntityView .Include(c => c.ClassTrainings) .ThenInclude(t => t.Training) .Include(c => c.ClassProgressions) + .Include(c => c.SubclassGroups) ), new Getter( EntityType.Feat, diff --git a/Pf2eDataScrapper/Helpers/ProcessProgress.cs b/Pf2eDataScrapper/Helpers/ProcessProgress.cs index 80514cb..ee6bfa1 100644 --- a/Pf2eDataScrapper/Helpers/ProcessProgress.cs +++ b/Pf2eDataScrapper/Helpers/ProcessProgress.cs @@ -1,4 +1,4 @@ -using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Definitions; namespace Pf2eDataScrapper.Helpers; diff --git a/Pf2eDataScrapper/ImportApplication.cs b/Pf2eDataScrapper/ImportApplication.cs index 3da4d97..0173c95 100644 --- a/Pf2eDataScrapper/ImportApplication.cs +++ b/Pf2eDataScrapper/ImportApplication.cs @@ -2,10 +2,9 @@ using System.ComponentModel; using System.Windows; using Microsoft.Extensions.DependencyInjection; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Processors; -using Pf2eDataScrapper.WPF; +using Pf2eDataScrapper.Processors.Collection; using Pf2eDataScrapper.WPF.EntityViewer; using Pf2eDataScrapper.WPF.ProgressForm; using Pf2eDataScrapper.WPF.StartForm; @@ -102,7 +101,7 @@ internal sealed class ImportApplication : Application _entityForm = ActivatorUtilities.CreateInstance(ServiceProvider); _entityForm.WindowStartupLocation = WindowStartupLocation.CenterScreen; _entityForm.Closing += Wpf_HandleFormClosing; - //_entityForm.ApplicationStateChange += ApplicationStateChange; + _entityForm.ApplicationStateChange += ApplicationStateChange; _entityForm.Show(); CurrentWpfForm = _entityForm; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Helpers/AonprdBuilderGlobals.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Helpers/AonprdBuilderGlobals.cs index 0446482..74633e4 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Helpers/AonprdBuilderGlobals.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Helpers/AonprdBuilderGlobals.cs @@ -1,4 +1,7 @@ using System.Collections.Generic; +using System.IO; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Pf2eModel.Model.Base.Targets; namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; @@ -16,108 +19,64 @@ internal class AonprdBuilderGlobals /// /// Словарь идентификаторов источников. /// - public Dictionary SourceIds { get; set; } = []; + public Dictionary SourceIds { get; } = []; /// /// Словарь идентификаторов признаков. /// - public Dictionary TraitIds { get; set; } = []; - - /// - /// Конструктор класса . - /// - public AonprdBuilderGlobals() { } - - /// - /// Получить суффикс для ссылки. - /// - /// Идентификатор Aounprd. - /// Суффикс для ссылки или пустая строка. - public string GetSlugSuffix(string id) - { - return SlugSuffixes.TryGetValue(id, out var slug) ? $"-{slug}" : string.Empty; - } + public Dictionary TraitIds { get; } = []; /// /// Словарей суффиксов для сущностей /// - public Dictionary SlugSuffixes { get; } = - new() - { - ["feat-5997"] = "legacy", - ["feat-5730"] = "dragonblood", - ["feat-6469"] = "general", - ["feat-4344"] = "archetype", - ["feat-3549"] = "vampire", - ["feat-7380"] = "mythic", - ["feat-5737"] = "dragonblood", - ["feat-6284"] = "bounty-hunter", - ["feat-2664"] = "archetype", - ["feat-6883"] = "kitsune", - ["feat-6209"] = "investigator", - ["feat-6477"] = "undead-slayer", - ["feat-7637"] = "dandy", - ["feat-7004"] = "yaoguai", - ["feat-4380"] = "stonebound", - }; + public Dictionary SlugSuffixes { get; } = []; /// /// Словарь допольнительных проверок связей. /// Ключ - устаревшая сущность, значение - обновлённая. /// - public Dictionary LegacyRemasterExtra { get; } = - new() - { - ["archetype-83"] = "archetype-129", - ["archetype-86"] = "archetype-198", - ["feat-5997"] = "feat-7108", - ["feat-4088"] = "feat-5491", - ["feat-1177"] = "feat-4553", - ["feat-2986"] = "feat-4340", - ["feat-1753"] = "feat-6031", - ["feat-2729"] = "feat-4077", - ["feat-480"] = "feat-4850", - ["feat-2989"] = "feat-4343", - ["feat-2987"] = "feat-4341", - ["feat-2990"] = "feat-4346", - ["feat-936"] = "feat-2269", - ["feat-2992"] = "feat-4350", - ["feat-2991"] = "feat-4349", - ["feat-2742"] = "feat-4078", - ["feat-1169"] = "feat-5055", - ["feat-2743"] = "feat-4079", - ["feat-963"] = "feat-4519", - ["feat-1171"] = "feat-4858", - ["feat-1167"] = "feat-5880", - ["feat-455"] = "feat-6007", - ["feat-2993"] = "feat-4352", - ["language-91"] = "language-180", - ["ritual-31"] = "ritual-191", - ["spell-571"] = "spell-1975", - ["spell-1052"] = "spell-1309", - ["spell-1053"] = "spell-1306", - ["spell-843"] = "spell-2376", - ["spell-578"] = "spell-1566", - ["spell-551"] = "spell-2003", - ["spell-553"] = "spell-2012", - ["spell-646"] = "spell-1394", - ["spell-1054"] = "spell-1305", - ["spell-559"] = "spell-2417", - ["spell-1055"] = "spell-1311", - ["spell-1056"] = "spell-1310", - ["spell-841"] = "spell-1107", - ["spell-1057"] = "spell-1307", - ["spell-560"] = "spell-2418", - ["spell-1058"] = "spell-1304", - ["spell-641"] = "spell-1413", - ["spell-1059"] = "spell-1308", - }; + public Dictionary LegacyRemasterExtra { get; } = []; /// /// Словарь сущностей, которые нужно слить с другой/другими. /// Ключ - пропускаемая сущность. Значение - целевая сущность. /// - public Dictionary MergeSources { get; } = new() { ["spell-654"] = "spell-819" }; + public Dictionary MergeSources { get; } = []; + + /// + /// Конструктор класса . + /// + public AonprdBuilderGlobals() + { + using StreamReader fileReader = new("Resources\\ImportAdaptation.json"); + + JObject? json = JObject + .Parse(fileReader.ReadToEnd()) + .SelectToken("Aonprd") + ?.ToObject(); + + if (json is not null) + { + SlugSuffixes = JsonToDictionary(json, "SlugSuffixes"); + LegacyRemasterExtra = JsonToDictionary(json, "LegacyRemasterExtra"); + MergeSources = JsonToDictionary(json, "MergeSources"); + } + } + + /// + /// Получить суффикс для ссылки. + /// + /// Идентификатор Aonprd. + /// Суффикс для ссылки или пустая строка. + public string GetSlugSuffix(string id) + { + return SlugSuffixes.TryGetValue(id, out string? slug) ? $"-{slug}" : string.Empty; + } + + private Dictionary JsonToDictionary(JObject json, string tokenPath) + { + return json.SelectToken(tokenPath)?.ToObject>() ?? []; + } } /* diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/AbstractEntityProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/AbstractEntityProcessor.cs index 2c4e175..94aa8d4 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/AbstractEntityProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/AbstractEntityProcessor.cs @@ -2,10 +2,11 @@ using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; using Pf2eModel; using Pf2eModel.Model; using Pf2eModel.Model.Base; @@ -60,6 +61,8 @@ internal abstract class AbstractEntityProcessor( /// public override void Process() { + Check(); + AddEntity(); AddSource(); AddExternal(); @@ -73,6 +76,17 @@ internal abstract class AbstractEntityProcessor( Context.SaveChanges(); } + /// + /// Проверки необходимости импорта сущности. + /// + public virtual void Check() + { + if (Globals.MergeSources.ContainsKey(Input.GetRequired("id"))) + { + throw new SkipItemException(Input.GetRequired("name"), "помечено на слияние."); + } + } + #region "Генерация описания" /// diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/AbstractSubclassProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/AbstractSubclassProcessor.cs index fac791d..9548329 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/AbstractSubclassProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/AbstractSubclassProcessor.cs @@ -1,8 +1,8 @@ using System.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; using Pf2eModel; using Pf2eModel.Model.Base; using Pf2eModel.Model.Common.I18n; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Common/ExternalProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Common/ExternalProcessor.cs index ca297c4..de49b73 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Common/ExternalProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Common/ExternalProcessor.cs @@ -1,6 +1,7 @@ -using Pf2eDataScrapper.App; -using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; +using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; using Pf2eModel; using Pf2eModel.Model.Base.Targets; @@ -12,7 +13,7 @@ namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Common; Group = ProcessorGroupEnum.AonprdPreparation )] [ProcessorDependencies(["aonprd:repository"])] -internal class ExternalProcessor(AonprdBuilderGlobals globals) : AbstractProcessor +internal class ExternalProcessor(AonprdBuilderGlobals globals) : AbstractSimpleProcessor { public Pf2eDbContext Context { get; } = new(); public AonprdBuilderGlobals Globals { get; } = globals; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Common/SkillProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Common/SkillProcessor.cs index 03c9666..768f45e 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Common/SkillProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Common/SkillProcessor.cs @@ -1,5 +1,6 @@ -using Pf2eDataScrapper.App; -using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; using Pf2eModel; using Pf2eModel.Model.Common; using Pf2eModel.Model.Common.I18n; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Common/SourceProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Common/SourceProcessor.cs index d8215ba..99c3b78 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Common/SourceProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Common/SourceProcessor.cs @@ -1,7 +1,8 @@ using System; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; using Pf2eModel; using Pf2eModel.Model.Base.Source; using Pf2eModel.Model.Enum; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Finalization/LegacyRemasterProcessors.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Finalization/LegacyRemasterProcessors.cs index 2961ffc..d63ad4e 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Finalization/LegacyRemasterProcessors.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Finalization/LegacyRemasterProcessors.cs @@ -1,10 +1,10 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; using Pf2eModel; using Pf2eModel.Model.Base; using Pf2eModel.Model.Base.Targets; @@ -21,7 +21,7 @@ namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Finalizat )] internal class LegacyRemasterProcessors(ProcessorInput input) : AbstractInputProcessor(input) { - private Pf2eDbContext Context { get; set; } = new(); + private Pf2eDbContext Context { get; } = new(); public override void Process() { @@ -32,27 +32,20 @@ internal class LegacyRemasterProcessors(ProcessorInput input) : AbstractInputPro int entityId = entity.EntityId; Entity legacyEntity = Context.Entities.FirstOrDefault(e => e.Id == entityId) - ?? throw new Exception($"Неизвестная сущность с ID {entityId}"); + ?? throw new($"Неизвестная сущность с ID {entityId}"); foreach (int remasterId in GetEntityIds("remaster_id")) { Context.LegacyRemasters.Add(new() { LegacyId = entityId, RemasterId = remasterId }); Entity remasterEntity = Context.Entities.AsNoTracking().FirstOrDefault(e => e.Id == remasterId) - ?? throw new Exception($"Неизвестная сущность с ID {remasterId}"); + ?? throw new($"Неизвестная сущность с ID {remasterId}"); if (legacyEntity.Slug == remasterEntity.Slug) { legacyEntity.Slug += "-legacy"; } } - - /* - foreach (int legacyId in GetEntityIds("legacy_id")) - { - Context.LegacyRemasters.Add(new() { LegacyId = legacyId, RemasterId = entityId }); - } - */ } protected List GetEntityIds(string path) diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Finalization/MissingLegacyRemasterProcessorFactory.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Finalization/MissingLegacyRemasterProcessorFactory.cs new file mode 100644 index 0000000..06dbc44 --- /dev/null +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Finalization/MissingLegacyRemasterProcessorFactory.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; +using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; +using Pf2eDataScrapper.Processors.Factory; +using Pf2eModel; +using Pf2eModel.Model.Base; +using Pf2eModel.Model.Base.Targets; + +namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Finalization; + +[ProcessorFactory( + "aonprd:fix-legacy-remaster", + ProcessorType = typeof(MissingLegacyRemasterProcessor), + Description = "Дополнение связяй устаревших и обновлённых сущностей", + Group = ProcessorGroupEnum.AonprdFinalization, + Parallel = true +)] +[ProcessorDependencies(["aonprd:legacy-remaster"])] +internal class MissingLegacyRemasterProcessorFactory( + IServiceProvider serviceProvider, + AonprdBuilderGlobals globals +) : AbstractProcessorFactory +{ + public IServiceProvider ServiceProvider { get; } = serviceProvider; + public AonprdBuilderGlobals Globals { get; } = globals; + + public override int Count() => Globals.LegacyRemasterExtra.Count; + + public override IEnumerable> GetEnumerator() + { + foreach ((string key, string value) in Globals.LegacyRemasterExtra) + { + yield return new( + $"{key} -> {value}", + ActivatorUtilities.CreateInstance( + ServiceProvider, + key, + value + ) + ); + } + } +} + +internal class MissingLegacyRemasterProcessor(string legacyId, string remasterId) : IProcessor +{ + public Pf2eDbContext Context { get; } = new(); + public string LegacyId { get; } = legacyId; + public string RemasterId { get; } = remasterId; + + private Entity GetEntity(string aonprdId) + { + EntityExternal entity = + Context.EntityExternals.AsNoTracking().FirstOrDefault(x => x.ExternalId == aonprdId) + ?? throw new SilentSkipItemException(); + + int entityId = entity.EntityId; + + return Context.Entities.FirstOrDefault(e => e.Id == entityId) + ?? throw new($"Неизвестная сущность с ID {entityId}"); + } + + public void Process() + { + Entity legacyEntity = GetEntity(LegacyId); + Entity remasterEntity = GetEntity(RemasterId); + + Context.LegacyRemasters.Add( + new() { LegacyId = legacyEntity.Id, RemasterId = remasterEntity.Id } + ); + + if (legacyEntity.Slug == remasterEntity.Slug) + { + legacyEntity.Slug += "-legacy"; + } + } + + public void Save() + { + Context.SaveChanges(); + } +} diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Preparation/CompendiumLoadProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Preparation/CompendiumLoadProcessor.cs index 57c53d9..fefcc86 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Preparation/CompendiumLoadProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Preparation/CompendiumLoadProcessor.cs @@ -1,9 +1,9 @@ using System.IO; using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium; -using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Preparation; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Preparation/RepositoryUpdateProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Preparation/RepositoryUpdateProcessor.cs index ce5d764..76f5ef4 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Preparation/RepositoryUpdateProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Preparation/RepositoryUpdateProcessor.cs @@ -1,6 +1,6 @@ -using Pf2eDataScrapper.App; -using Pf2eDataScrapper.Helpers; -using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Helpers; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Preparation; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Preparation/SchemaBuildProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Preparation/SchemaBuildProcessor.cs index 2fe2017..3613d04 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Preparation/SchemaBuildProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Preparation/SchemaBuildProcessor.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium; +using Pf2eDataScrapper.Processors.Attributes; using Pf2eDataScrapper.SchemaBuilder; namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Preparation; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Subclasses/ApparitionProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Subclasses/ApparitionProcessor.cs index 7dd7b8e..439e16f 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Subclasses/ApparitionProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Subclasses/ApparitionProcessor.cs @@ -1,9 +1,10 @@ using System.Collections.Generic; using System.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Collection; using Pf2eModel; using Pf2eModel.Model.Base; using Pf2eModel.Model.Common; @@ -19,8 +20,7 @@ namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Subclasse InnerType = "apparition", CompendiumType = ProcessorCompendiumEnum.Aonprd, Description = "Apparitions", - Group = ProcessorGroupEnum.AonprdSubclasses, - Active = false + Group = ProcessorGroupEnum.AonprdSubclasses )] [ProcessorDependencies( ["aonprd:trait", "aonprd:source", "aonprd:class", "aonprd:spell", "aonprd:skill"] diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/ActionProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/ActionProcessor.cs index e142199..b9a781c 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/ActionProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/ActionProcessor.cs @@ -1,7 +1,8 @@ -using Pf2eDataScrapper.App; -using Pf2eDataScrapper.Helpers; +using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Collection; using Pf2eModel.Model.Enum; using StringHelper = Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers.StringHelper; @@ -42,8 +43,10 @@ internal class ActionProcessor( Object.Extra = GenerateJsonString("school"); } - public void Check() + public override void Check() { + base.Check(); + if (Input.GetRequired("markdown").StartsWith("**Activate")) { throw new SkipItemException(Input.GetRequired("name"), "activating action"); diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/AncestryProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/AncestryProcessor.cs index babaafc..d0d6c1a 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/AncestryProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/AncestryProcessor.cs @@ -2,10 +2,11 @@ using System.Collections.Generic; using System.Linq; using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Collection; using Pf2eModel.Model.Enum; using Pf2eModel.Model.Structure; using StringHelper = Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers.StringHelper; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/ArchetypeProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/ArchetypeProcessor.cs index dfbfa11..d299727 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/ArchetypeProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/ArchetypeProcessor.cs @@ -1,7 +1,8 @@ -using Pf2eDataScrapper.App; -using Pf2eDataScrapper.Helpers; +using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Collection; using Pf2eModel.Model.Enum; using Pf2eModel.Model.Structure; using StringHelper = Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers.StringHelper; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/BackgroundProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/BackgroundProcessor.cs index 7408247..ff7b782 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/BackgroundProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/BackgroundProcessor.cs @@ -1,8 +1,9 @@ using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Collection; using Pf2eModel.Model.Enum; using Pf2eModel.Model.Structure; using Pf2eModel.Model.Structure.BackgroundRelation; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/ClassProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/ClassProcessor.cs index 8047147..2d50737 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/ClassProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/ClassProcessor.cs @@ -3,10 +3,11 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Collection; using Pf2eModel; using Pf2eModel.Model.Common; using Pf2eModel.Model.Common.I18n; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/FeatProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/FeatProcessor.cs index 6697968..fe4e806 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/FeatProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/FeatProcessor.cs @@ -1,9 +1,9 @@ using System.Linq; using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; using Pf2eModel; using Pf2eModel.Model.Enum; using Pf2eModel.Model.Structure; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/LanguageProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/LanguageProcessor.cs index 9cfc4ef..4b3cb42 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/LanguageProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/LanguageProcessor.cs @@ -1,7 +1,7 @@ -using Pf2eDataScrapper.App; -using Pf2eDataScrapper.Helpers; +using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; using Pf2eModel.Model.Enum; using Pf2eModel.Model.Structure; using StringHelper = Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers.StringHelper; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/RitualProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/RitualProcessor.cs index dc658a5..524dc01 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/RitualProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/RitualProcessor.cs @@ -3,10 +3,10 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; using Pf2eModel; using Pf2eModel.Model.Common.I18n; using Pf2eModel.Model.Enum; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/Rules/RuleProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/Rules/RuleProcessor.cs index eb6deb2..b5fe866 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/Rules/RuleProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/Rules/RuleProcessor.cs @@ -1,9 +1,9 @@ using System.Linq; using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; using Pf2eModel.Model.Base.Source; using Pf2eModel.Model.Base.Targets; using Pf2eModel.Model.Common.I18n; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/Rules/RulesOrderProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/Rules/RulesOrderProcessor.cs index 7d0b629..c5f09ab 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/Rules/RulesOrderProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/Rules/RulesOrderProcessor.cs @@ -7,9 +7,9 @@ using System.Collections.Generic; using System.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; -using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; using Pf2eModel; using Rule = Pf2eModel.Model.Structure.Rule; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/Rules/RulesTocProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/Rules/RulesTocProcessor.cs index af2f841..592cc74 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/Rules/RulesTocProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/Rules/RulesTocProcessor.cs @@ -4,9 +4,9 @@ using System.Text.RegularExpressions; using System.Web; using AngleSharp; using AngleSharp.Dom; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; -using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; using Pf2eModel; using Pf2eModel.Model.Base.Source; @@ -120,7 +120,8 @@ internal partial class RulesTocProcessor(Pf2eDbContext context) : IProcessor IDocument document = null!; bool completed = false; - while (!completed){ + while (!completed) + { try { document = context.OpenAsync(Url).Result; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/SpellProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/SpellProcessor.cs index 3f46668..4e33470 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/SpellProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/SpellProcessor.cs @@ -1,10 +1,10 @@ using System.Collections.Generic; using System.Linq; using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; using Pf2eModel.Model.Common.I18n; using Pf2eModel.Model.Enum; using Pf2eModel.Model.Structure; diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/TraitProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/TraitProcessor.cs index 033ece3..0d179ff 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/TraitProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/Types/TraitProcessor.cs @@ -1,7 +1,7 @@ -using Pf2eDataScrapper.App; -using Pf2eDataScrapper.Helpers; +using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; using Pf2eModel.Model.Common.I18n; using Pf2eModel.Model.Enum; using Pf2eModel.Model.Structure; diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ActionProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ActionProcessor.cs index 93777b2..34e192b 100644 --- a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ActionProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ActionProcessor.cs @@ -1,7 +1,8 @@ using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Collection; using Pf2eModel; using Pf2eModel.Model.Enum; diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ConditionProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ConditionProcessor.cs index 1c34cbd..5cf90a3 100644 --- a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ConditionProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ConditionProcessor.cs @@ -1,7 +1,8 @@ using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Collection; using Pf2eModel; using Pf2eModel.Model.Enum; using Pf2eModel.Model.Structure; diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/FoundryEnAbstractProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/FoundryEnAbstractProcessor.cs index 214e593..4459b3b 100644 --- a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/FoundryEnAbstractProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/FoundryEnAbstractProcessor.cs @@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore; using Newtonsoft.Json.Linq; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Definitions; using Pf2eModel; using Pf2eModel.Model; using Pf2eModel.Model.Base; diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/CompendiumFolderProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/CompendiumFolderProcessor.cs index 74a8e3c..f1f4532 100644 --- a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/CompendiumFolderProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/CompendiumFolderProcessor.cs @@ -1,8 +1,8 @@ using System.IO; using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium; -using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors.Preparation; diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/CompendiumItemsProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/CompendiumItemsProcessor.cs index 5093b44..79d6eea 100644 --- a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/CompendiumItemsProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/CompendiumItemsProcessor.cs @@ -2,10 +2,10 @@ using System.IO; using System.Linq; using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium; -using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors.Preparation; diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/RepositoryUpdateProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/RepositoryUpdateProcessor.cs index 2d25747..3af769a 100644 --- a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/RepositoryUpdateProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/RepositoryUpdateProcessor.cs @@ -1,6 +1,6 @@ -using Pf2eDataScrapper.App; -using Pf2eDataScrapper.Helpers; -using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Helpers; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors.Preparation; diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/SchemaBuildProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/SchemaBuildProcessor.cs index 1cac93c..36c5ee8 100644 --- a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/SchemaBuildProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/SchemaBuildProcessor.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium; +using Pf2eDataScrapper.Processors.Attributes; using Pf2eDataScrapper.SchemaBuilder; namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors.Preparation; diff --git a/Pf2eDataScrapper/Pf2eDataScrapper.csproj b/Pf2eDataScrapper/Pf2eDataScrapper.csproj index 13cb96a..876b404 100644 --- a/Pf2eDataScrapper/Pf2eDataScrapper.csproj +++ b/Pf2eDataScrapper/Pf2eDataScrapper.csproj @@ -35,6 +35,9 @@ Always + + Always + Always diff --git a/Pf2eDataScrapper/Processors/Attributes/AbstractProcessorAttribute.cs b/Pf2eDataScrapper/Processors/Attributes/AbstractProcessorAttribute.cs new file mode 100644 index 0000000..22c7f87 --- /dev/null +++ b/Pf2eDataScrapper/Processors/Attributes/AbstractProcessorAttribute.cs @@ -0,0 +1,35 @@ +using System; + +namespace Pf2eDataScrapper.Processors.Attributes; + +/// +/// Абстрактный аттрибут обработчика. +/// +[AttributeUsage(AttributeTargets.Class)] +internal class AbstractProcessorAttribute(string name) : Attribute +{ + /// + /// Название обработчика. + /// + public string Name { get; } = name; + + /// + /// Описание обработчика. + /// + public string Description { get; init; } = name; + + /// + /// Группа обработчиков, к которому относится обработчик. + /// + public ProcessorGroupEnum Group { get; init; } = ProcessorGroupEnum.General; + + /// + /// Процессор включён по умолчанию. + /// + public bool Active { get; init; } = true; + + /// + /// Разрешить выполнять процессов в параллельном режиме + /// + public bool Parallel { get; init; } = false; +} diff --git a/Pf2eDataScrapper/Processors/Attributes/ProcessorAttribute.cs b/Pf2eDataScrapper/Processors/Attributes/ProcessorAttribute.cs new file mode 100644 index 0000000..213a9bf --- /dev/null +++ b/Pf2eDataScrapper/Processors/Attributes/ProcessorAttribute.cs @@ -0,0 +1,10 @@ +using System; + +namespace Pf2eDataScrapper.Processors.Attributes; + +/// +/// Общий аттрибут обработчика. +/// +/// Название обработчика. +[AttributeUsage(AttributeTargets.Class)] +internal class ProcessorAttribute(string name) : AbstractProcessorAttribute(name) { } diff --git a/Pf2eDataScrapper/Processors/Attributes/ProcessorCollectionAttribute.cs b/Pf2eDataScrapper/Processors/Attributes/ProcessorCollectionAttribute.cs new file mode 100644 index 0000000..a6d47cd --- /dev/null +++ b/Pf2eDataScrapper/Processors/Attributes/ProcessorCollectionAttribute.cs @@ -0,0 +1,22 @@ +using System; + +namespace Pf2eDataScrapper.Processors.Attributes; + +/// +/// Аттрибут обработчика набор элементов. +/// +/// Название обработчика. +[AttributeUsage(AttributeTargets.Class)] +internal class ProcessorCollectionAttribute(string name) : AbstractProcessorAttribute(name) +{ + /// + /// Название типов, который обрабатывает этот оброботчик. + /// null - обработать все типы. + /// + public required string? InnerType { get; init; } + + /// + /// Тип используемого компендиума. + /// + public required ProcessorCompendiumEnum CompendiumType { get; init; } +} diff --git a/Pf2eDataScrapper/Processors/Attributes/ProcessorDependenciesAttribute.cs b/Pf2eDataScrapper/Processors/Attributes/ProcessorDependenciesAttribute.cs new file mode 100644 index 0000000..7f0b620 --- /dev/null +++ b/Pf2eDataScrapper/Processors/Attributes/ProcessorDependenciesAttribute.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; + +namespace Pf2eDataScrapper.Processors.Attributes; + +/// +/// Аттрибут зависимостей обработчика. +/// +/// Коллекция названий обработчиков, которые должны быть выполнены до этого оброботчика. +[AttributeUsage(AttributeTargets.Class)] +public class ProcessorDependenciesAttribute(string[] dependencies) : Attribute +{ + /// + /// Коллекция названий обработчиков, которые должны быть выполнены до этого оброботчика. + /// + public ICollection Dependencies { get; } = dependencies; +} diff --git a/Pf2eDataScrapper/Processors/Attributes/ProcessorFactoryAttribute.cs b/Pf2eDataScrapper/Processors/Attributes/ProcessorFactoryAttribute.cs new file mode 100644 index 0000000..fd25403 --- /dev/null +++ b/Pf2eDataScrapper/Processors/Attributes/ProcessorFactoryAttribute.cs @@ -0,0 +1,11 @@ +using System; + +namespace Pf2eDataScrapper.Processors.Attributes; + +internal class ProcessorFactoryAttribute(string name) : AbstractProcessorAttribute(name) +{ + /// + /// Тип обрабатывающего процессора + /// + public required Type ProcessorType { get; init; } +} diff --git a/Pf2eDataScrapper/App/ProcessorGroupEnum.cs b/Pf2eDataScrapper/Processors/Attributes/ProcessorGroupEnum.cs similarity index 89% rename from Pf2eDataScrapper/App/ProcessorGroupEnum.cs rename to Pf2eDataScrapper/Processors/Attributes/ProcessorGroupEnum.cs index 563e41e..e03caf4 100644 --- a/Pf2eDataScrapper/App/ProcessorGroupEnum.cs +++ b/Pf2eDataScrapper/Processors/Attributes/ProcessorGroupEnum.cs @@ -1,7 +1,7 @@ using System.ComponentModel; using System.Reflection; -namespace Pf2eDataScrapper.App; +namespace Pf2eDataScrapper.Processors.Attributes; public enum ProcessorGroupEnum { @@ -33,6 +33,13 @@ public enum ProcessorCompendiumEnum FoundryEn, } +public enum ProcessorFactoryTypeEnum +{ + Simple, + Compendium, + Iterator, +} + public static class ProcessorGroupEnumExtension { public static string GetDescription(this ProcessorGroupEnum group) diff --git a/Pf2eDataScrapper/Processors/Collection/ProcessorCollection.cs b/Pf2eDataScrapper/Processors/Collection/ProcessorCollection.cs new file mode 100644 index 0000000..f174806 --- /dev/null +++ b/Pf2eDataScrapper/Processors/Collection/ProcessorCollection.cs @@ -0,0 +1,296 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using LinqToDB; +using Microsoft.Extensions.DependencyInjection; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; +using Pf2eDataScrapper.Processors.Factory; + +namespace Pf2eDataScrapper.Processors.Collection; + +/// +/// Класс с коллекцией обработчиков. +/// +internal class ProcessorCollection +{ + public IServiceProvider ServiceProvider { get; } + + /// + /// Коллекция всех доступных обработчиков. + /// + public ICollection AllItems { get; } = []; + + /// + /// Коллекция обработчиков, которые будут обрабатываться. + /// Для изменения необходимо использовать . + /// + public List Items { get; private set; } = []; + + /// + /// Обеспечение доступа к элементам обработчиков. + /// + /// + /// + public ProcessorRecord this[string name] => AllItems.First(item => item.Name == name); + + /// + /// Конструктор класса . + /// + public ProcessorCollection(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + Assembly assembly = Assembly.GetExecutingAssembly(); + + foreach (Type type in assembly.GetTypes()) + { + ProcessType(type, type.GetCustomAttribute()); + } + + CheckDependencies(); + FilterProcessors([]); + } + + private void ProcessType(Type type, AbstractProcessorAttribute? attribute) + { + switch (attribute) + { + case null: + break; + + case ProcessorAttribute processorAttribute: + ProcessType(type, processorAttribute); + break; + + case ProcessorCollectionAttribute processorCollectionAttribute: + ProcessType(type, processorCollectionAttribute); + break; + + case ProcessorFactoryAttribute processorFactoryAttribute: + ProcessType(type, processorFactoryAttribute); + break; + + default: + throw new( + $"Неизвестная реализация класса {typeof(AbstractProcessorAttribute)} - {attribute.GetType()}" + ); + } + } + + private void ProcessType(Type type, ProcessorAttribute? attribute) + { + if (attribute is null) + { + return; + } + + if (!type.IsAssignableTo(typeof(IProcessor))) + { + throw new( + $"Процессор {type}, которому установлен аттрибут {attribute.GetType()}, не представляет интерфейс {typeof(IProcessor)}" + ); + } + + ProcessorDependenciesAttribute? dependenciesAttribute = + type.GetCustomAttribute(); + + ProcessorRecord item = new() + { + Name = attribute.Name, + Type = type, + Description = attribute.Description, + Group = attribute.Group, + Dependencies = dependenciesAttribute?.Dependencies ?? [], + Active = attribute.Active, + Parallel = attribute.Parallel, + }; + + item.Factory = ActivatorUtilities.CreateInstance( + ServiceProvider, + item + ); + + AllItems.Add(item); + } + + private void ProcessType(Type type, ProcessorCollectionAttribute? attribute) + { + if (attribute is null) + { + return; + } + + if (!type.IsAssignableTo(typeof(AbstractInputProcessor))) + { + throw new( + $"Процессор {type}, которому установлен аттрибут {attribute.GetType()}, не реализует класс {typeof(AbstractInputProcessor)}." + ); + } + + ProcessorDependenciesAttribute? dependenciesAttribute = + type.GetCustomAttribute(); + + ProcessorRecord item = new() + { + Name = attribute.Name, + Type = type, + Description = attribute.Description, + Group = attribute.Group, + Dependencies = dependenciesAttribute?.Dependencies ?? [], + Active = attribute.Active, + Parallel = attribute.Parallel, + }; + + CompendiumProcessorFactory factory = + ActivatorUtilities.CreateInstance(ServiceProvider, item); + + factory.CompendiumType = attribute.CompendiumType; + factory.InnerType = attribute.InnerType; + + item.Factory = factory; + + AllItems.Add(item); + } + + private void ProcessType(Type type, ProcessorFactoryAttribute? attribute) + { + if (attribute is null) + { + return; + } + + if (!type.IsAssignableTo(typeof(AbstractProcessorFactory))) + { + throw new( + $"Процессор {type}, которому установлен аттрибут {attribute.GetType()}, не реализует класс {typeof(AbstractProcessorFactory)}." + ); + } + + ProcessorDependenciesAttribute? dependenciesAttribute = + type.GetCustomAttribute(); + + ProcessorRecord item = new() + { + Name = attribute.Name, + Type = attribute.ProcessorType, + Description = attribute.Description, + Group = attribute.Group, + Dependencies = dependenciesAttribute?.Dependencies ?? [], + Active = attribute.Active, + Parallel = attribute.Parallel, + Factory = (AbstractProcessorFactory) + ActivatorUtilities.CreateInstance(ServiceProvider, type), + }; + + AllItems.Add(item); + } + + /// + /// Проверка, что все зависимости всех обработчиков могут быть удовлетворены. + /// + private void CheckDependencies() + { + foreach (ProcessorRecord item in Items) + { + foreach (string dependency in item.Dependencies) + { + if (Items.All(i => i.Name != dependency)) + { + throw new($"Dependency '{dependency}' for processor '{item.Name}' not found."); + } + } + } + } + + /// + /// Сортировать обработчики в соответсвии со всеми зависимостями. + /// + public void SortItems() + { + Items.ForEach(item => item.Priority = -1); + + Dictionary priorities = []; + + while (priorities.Count < Items.Count) + { + foreach (ProcessorRecord item in Items) + { + if (item.Priority >= 0) + { + continue; + } + + IEnumerable dependencyPriorities = item.Dependencies.Select(d => + priorities.GetValueOrDefault(d, -1) + ); + + if (dependencyPriorities.Any(p => p == -1)) + { + continue; + } + + item.Priority = Math.Max( + dependencyPriorities.Any() ? dependencyPriorities.Max() + 1 : 1, + (int)item.Group * 100 + ); + priorities.Add(item.Name, item.Priority); + } + } + + Items.Sort((a, b) => a.Priority - b.Priority); + } + + /// + /// Ограничить список используемых обработчиков по названию. + /// Автоматически включает все обработчики, от которых зависят указанные в аргументе обработчики. + /// + /// Коллекция названиий требуемых обработчиков. + public void FilterProcessors(ICollection processorNames) + { + if (processorNames.Count == 0) + { + Items = [.. AllItems]; + SortItems(); + return; + } + + Dictionary nameFlags = processorNames.ToDictionary(name => name, _ => false); + + while (nameFlags.Values.Any(v => !v)) + { + foreach ( + KeyValuePair pair in nameFlags.Where(pair => !pair.Value).ToList() + ) + { + ProcessorRecord item = AllItems.First(item => item.Name == pair.Key); + + foreach (string dependency in item.Dependencies) + { + nameFlags.TryAdd(dependency, false); + } + + nameFlags[pair.Key] = true; + } + } + + Items = AllItems.Where(item => nameFlags.ContainsKey(item.Name)).ToList(); + } + + /// + /// Получить список типов, которые обрабатываются в компендиуме. + /// + /// Тип компендиума. + /// Набор типов. + public ICollection GetTypesOfCompendium(ProcessorCompendiumEnum compendium) => + Items + .Where(item => + item.Factory.GetType().IsAssignableTo(typeof(CompendiumProcessorFactory)) + ) + .Where(item => + (item.Factory as CompendiumProcessorFactory)!.CompendiumType == compendium + ) + .Select(item => (item.Factory as CompendiumProcessorFactory)!.InnerType) + .OfType() + .ToList(); +} diff --git a/Pf2eDataScrapper/Processors/Collection/ProcessorRecord.cs b/Pf2eDataScrapper/Processors/Collection/ProcessorRecord.cs new file mode 100644 index 0000000..93bd2d2 --- /dev/null +++ b/Pf2eDataScrapper/Processors/Collection/ProcessorRecord.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Factory; + +namespace Pf2eDataScrapper.Processors.Collection; + +/// +/// Элемент коллекции обработчиков. +/// +internal class ProcessorRecord +{ + /// + /// Название обработчика. + /// + public required string Name { get; init; } + + /// + /// Тип класса обработчика. + /// + public required Type Type { get; init; } + + /// + /// Описание обработчика. + /// + public string Description { get; init; } = ""; + + /// + /// Фабрика обработчиков. + /// + public AbstractProcessorFactory Factory { get; set; } = null!; + + /// + /// Группа обработчика. + /// + public required ProcessorGroupEnum Group { get; init; } + + /// + /// Коллекция названий обработчиков, после которых должен выполняться обработчик. + /// + public ICollection Dependencies { get; init; } = []; + + /// + /// Процессор включён по умолчанию. + /// + public bool Active { get; init; } = true; + + /// + /// Приоритет выполнения обработчика. + /// + public int Priority { get; set; } = -1; + + /// + /// Разрешить выполнять процессов в параллельном режиме + /// + public bool Parallel { get; init; } = true; +} diff --git a/Pf2eDataScrapper/Processors/AbstractInputProcessor.cs b/Pf2eDataScrapper/Processors/Definitions/AbstractInputProcessor.cs similarity index 91% rename from Pf2eDataScrapper/Processors/AbstractInputProcessor.cs rename to Pf2eDataScrapper/Processors/Definitions/AbstractInputProcessor.cs index aae8786..17fc8f2 100644 --- a/Pf2eDataScrapper/Processors/AbstractInputProcessor.cs +++ b/Pf2eDataScrapper/Processors/Definitions/AbstractInputProcessor.cs @@ -1,6 +1,6 @@ -using Pf2eDataScrapper.App; +using Pf2eDataScrapper.Processors.Attributes; -namespace Pf2eDataScrapper.Processors; +namespace Pf2eDataScrapper.Processors.Definitions; /// /// Абстрактный класс-обработчик данных, полученных из Архивов Нефиса. diff --git a/Pf2eDataScrapper/Processors/AbstractProcessor.cs b/Pf2eDataScrapper/Processors/Definitions/AbstractSimpleProcessor.cs similarity index 82% rename from Pf2eDataScrapper/Processors/AbstractProcessor.cs rename to Pf2eDataScrapper/Processors/Definitions/AbstractSimpleProcessor.cs index 216dfc9..3cab212 100644 --- a/Pf2eDataScrapper/Processors/AbstractProcessor.cs +++ b/Pf2eDataScrapper/Processors/Definitions/AbstractSimpleProcessor.cs @@ -1,6 +1,6 @@ -using Pf2eDataScrapper.App; +using Pf2eDataScrapper.Processors.Attributes; -namespace Pf2eDataScrapper.Processors; +namespace Pf2eDataScrapper.Processors.Definitions; /// /// Абстрактный класс-обработчик данных, полученных из Архивов Нефиса. @@ -8,7 +8,7 @@ namespace Pf2eDataScrapper.Processors; /// для которых указан атрибут . /// /// -internal abstract class AbstractProcessor : IProcessor +internal abstract class AbstractSimpleProcessor : IProcessor { /// /// Основной метод обработки данных. diff --git a/Pf2eDataScrapper/Processors/IProcessor.cs b/Pf2eDataScrapper/Processors/Definitions/IProcessor.cs similarity index 85% rename from Pf2eDataScrapper/Processors/IProcessor.cs rename to Pf2eDataScrapper/Processors/Definitions/IProcessor.cs index 09c675a..6a880a2 100644 --- a/Pf2eDataScrapper/Processors/IProcessor.cs +++ b/Pf2eDataScrapper/Processors/Definitions/IProcessor.cs @@ -1,4 +1,4 @@ -namespace Pf2eDataScrapper.Processors; +namespace Pf2eDataScrapper.Processors.Definitions; public interface IProcessor { diff --git a/Pf2eDataScrapper/Processors/Factory/AbstractProcessorFactory.cs b/Pf2eDataScrapper/Processors/Factory/AbstractProcessorFactory.cs new file mode 100644 index 0000000..672b4fe --- /dev/null +++ b/Pf2eDataScrapper/Processors/Factory/AbstractProcessorFactory.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using Pf2eDataScrapper.Processors.Collection; +using Pf2eDataScrapper.Processors.Definitions; + +namespace Pf2eDataScrapper.Processors.Factory; + +/// +/// Абстрактная фабрика создания процессоров. +/// +internal abstract class AbstractProcessorFactory +{ + /// + /// Подготовить фабрику к работе. + /// + public virtual void Prepare() { } + + /// + /// Количество элеметов для итерирования. + /// + /// Количество элеметов + public abstract int Count(); + + /// + /// Итератор процессоров. + /// + /// Пара значений: [0] - описание элемента процессор, [1] - процессор. + public abstract IEnumerable> GetEnumerator(); +} diff --git a/Pf2eDataScrapper/Processors/Factory/CompendiumProcessorFactory.cs b/Pf2eDataScrapper/Processors/Factory/CompendiumProcessorFactory.cs new file mode 100644 index 0000000..bb2b5dc --- /dev/null +++ b/Pf2eDataScrapper/Processors/Factory/CompendiumProcessorFactory.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json.Linq; +using Pf2eDataScrapper.Importers; +using Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium; +using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Collection; +using Pf2eDataScrapper.Processors.Definitions; + +namespace Pf2eDataScrapper.Processors.Factory; + +internal class CompendiumProcessorFactory(ProcessorRecord item, IServiceProvider serviceProvider) + : AbstractProcessorFactory +{ + public ProcessorRecord Item { get; } = item; + public IServiceProvider ServiceProvider { get; } = serviceProvider; + + public ProcessorCompendiumEnum? CompendiumType { get; set; } = null; + public string? InnerType { get; set; } = null; + + public AbstractCompendium Compendium { get; private set; } = null!; + public ICollection Types { get; private set; } = []; + + public override void Prepare() + { + if (CompendiumType is null) + { + throw new ArgumentNullException(nameof(CompendiumType)); + } + + base.Prepare(); + + ProcessorCollection collection = + ServiceProvider.GetService() ?? throw new(); + + Compendium = + CompendiumType switch + { + ProcessorCompendiumEnum.Aonprd => ServiceProvider.GetService(), + ProcessorCompendiumEnum.FoundryEn => + ServiceProvider.GetService(), + _ => (AbstractCompendium?)null, + } ?? throw new($"Не могу выбрать импортёр для группы {Item.Group}"); + + Types = InnerType is null + ? collection.GetTypesOfCompendium(CompendiumType ?? throw new()) + : [InnerType]; + } + + public override int Count() => Compendium.Count(Types); + + public override IEnumerable> GetEnumerator() + { + foreach ((AbstractCompendiumItem compendiumItem, JObject json) in Compendium.Iterate(Types)) + { + ProcessorInput processorInput = ActivatorUtilities.CreateInstance( + ServiceProvider, + compendiumItem.Id, + json + ); + + yield return new( + compendiumItem.Id, + (IProcessor) + ActivatorUtilities.CreateInstance(ServiceProvider, Item.Type, processorInput) + ); + } + } +} diff --git a/Pf2eDataScrapper/Processors/Factory/SimpleProcessorFactory.cs b/Pf2eDataScrapper/Processors/Factory/SimpleProcessorFactory.cs new file mode 100644 index 0000000..04188f5 --- /dev/null +++ b/Pf2eDataScrapper/Processors/Factory/SimpleProcessorFactory.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Pf2eDataScrapper.Processors.Collection; +using Pf2eDataScrapper.Processors.Definitions; + +namespace Pf2eDataScrapper.Processors.Factory; + +internal class SimpleProcessorFactory(ProcessorRecord item, IServiceProvider serviceProvider) + : AbstractProcessorFactory +{ + public ProcessorRecord Item { get; } = item; + public IServiceProvider ServiceProvider { get; } = serviceProvider; + + public override int Count() => 1; + + public override IEnumerable> GetEnumerator() + { + yield return new( + Item.Description, + (IProcessor)ActivatorUtilities.CreateInstance(ServiceProvider, Item.Type) + ); + } +} diff --git a/Pf2eDataScrapper/Processors/General/DatabaseTruncateProcessor.cs b/Pf2eDataScrapper/Processors/General/DatabaseTruncateProcessor.cs index ce8a65a..64e7d11 100644 --- a/Pf2eDataScrapper/Processors/General/DatabaseTruncateProcessor.cs +++ b/Pf2eDataScrapper/Processors/General/DatabaseTruncateProcessor.cs @@ -1,4 +1,5 @@ -using Pf2eDataScrapper.App; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Definitions; using Pf2eModel; namespace Pf2eDataScrapper.Processors.General; diff --git a/Pf2eDataScrapper/Processors/ProcessorExecutor.cs b/Pf2eDataScrapper/Processors/ProcessorExecutor.cs index b0e22d2..09f0a8e 100644 --- a/Pf2eDataScrapper/Processors/ProcessorExecutor.cs +++ b/Pf2eDataScrapper/Processors/ProcessorExecutor.cs @@ -2,30 +2,21 @@ using System.Collections.Generic; using System.ComponentModel; using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.App; using Pf2eDataScrapper.Helpers; -using Pf2eDataScrapper.Importers; -using Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium; -using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium; +using Pf2eDataScrapper.Processors.Collection; +using Pf2eDataScrapper.Processors.Definitions; +using Pf2eDataScrapper.Processors.Factory; namespace Pf2eDataScrapper.Processors; internal sealed class ProcessorExecutor( - IServiceProvider serviceProvider, ProcessorCollection collection, ProcessProgress progress, - AonprdCompendium aonprdCompendium, - FoundryEnCompendium foundryEnCompendium, ApplicationSettings settings ) { - public IServiceProvider ServiceProvider { get; } = serviceProvider; public ProcessorCollection Collection { get; } = collection; public ProcessProgress Progress { get; } = progress; - public AonprdCompendium AonprdCompendium { get; } = aonprdCompendium; - public FoundryEnCompendium FoundryEnCompendium { get; } = foundryEnCompendium; public ApplicationSettings Settings { get; } = settings; public void Start() @@ -39,23 +30,25 @@ internal sealed class ProcessorExecutor( private int _currentIndex; + private AbstractProcessorFactory CurrentFactory { get; set; } = null!; + private void StartItem() { - ProcessorCollectionItem item = Collection.Items[_currentIndex]; + ProcessorRecord item = Collection.Items[_currentIndex]; Progress.Processors.Start(item.Description); Progress.Progress(Progress.Processors.ToString()); BackgroundWorker worker = new(); + CurrentFactory = item.Factory; + CurrentFactory.Prepare(); + worker.DoWork += (_, _) => { Parallel.ForEach( - IterateProcessors(item), - new ParallelOptions() - { - MaxDegreeOfParallelism = item.Parallel ? Settings.MaxThreads : 1, - }, + IterateProcessors(), + new() { MaxDegreeOfParallelism = item.Parallel ? Settings.MaxThreads : 1 }, RunProcessor ); }; @@ -94,53 +87,18 @@ internal sealed class ProcessorExecutor( else { Progress.Processors.Complete(); - Progress.Complete(); } } - private IEnumerable IterateProcessors(ProcessorCollectionItem item) + private IEnumerable IterateProcessors() { - if (!item.IsCollection) + Progress.Local.Reset(CurrentFactory.Count()); + + foreach ((string title, IProcessor processor) in CurrentFactory.GetEnumerator()) { - Progress.Local.Reset(1); - Progress.Local.Start(item.Description); - yield return (IProcessor)ActivatorUtilities.CreateInstance(ServiceProvider, item.Type); - Progress.Local.Complete(); - yield break; - } + Progress.Local.Start(title); - if (item.Group == ProcessorGroupEnum.General) - { - throw new( - $"Обработчик {item.Description} помечен как общий (поле Group == General) и коллекционный (поле InnerType), что запрещено." - ); - } - - AbstractCompendium compendium = item.Compendium switch - { - ProcessorCompendiumEnum.Aonprd => AonprdCompendium, - ProcessorCompendiumEnum.FoundryEn => FoundryEnCompendium, - _ => throw new($"Не могу выбрать импортёр для группы {item.Group}"), - }; - - ICollection types = item.InnerType is null - ? Collection.GetTypesOfCompendium(item.Compendium ?? throw new("impossible")) - : [item.InnerType]; - - Progress.Local.Reset(compendium.Count(types)); - - foreach ((AbstractCompendiumItem compendiumItem, JObject json) in compendium.Iterate(types)) - { - Progress.Local.Start(compendiumItem.Id); - - ProcessorInput processorInput = ActivatorUtilities.CreateInstance( - ServiceProvider, - compendiumItem.Id, - json - ); - - yield return (IProcessor) - ActivatorUtilities.CreateInstance(ServiceProvider, item.Type, processorInput); + yield return processor; Progress.Local.End(); } diff --git a/Pf2eDataScrapper/Resources/ImportAdaptation.json b/Pf2eDataScrapper/Resources/ImportAdaptation.json new file mode 100644 index 0000000..c9a36d1 --- /dev/null +++ b/Pf2eDataScrapper/Resources/ImportAdaptation.json @@ -0,0 +1,82 @@ +{ + "Aonprd": { + "SlugSuffixes": { + "feat-455": "initial", + "spell-843": "initial", + "feat-2664": "archetype", + "feat-3247": "game-hunter", + "feat-3477": "undead-slayer", + "feat-3549": "vampire", + "feat-4344": "archetype", + "feat-4380": "stonebound", + "feat-5730": "dragonblood", + "feat-5737": "dragonblood", + "feat-5997": "legacy", + "feat-6209": "investigator", + "feat-6469": "general", + "feat-6477": "undead-slayer", + "feat-6883": "kitsune", + "feat-7004": "yaoguai", + "feat-7380": "mythic", + "feat-7637": "dandy" + }, + "LegacyRemasterExtra": { + "action-14": "action-2273", + "action-15": "action-2275", + "action-558": "action-2277", + + "archetype-83": "archetype-129", + "archetype-86": "archetype-198", + + "feat-455": "feat-6007", + "feat-480": "feat-4850", + "feat-936": "feat-2269", + "feat-1177": "feat-4553", + "feat-1753": "feat-6031", + "feat-2117": "feat-7577", + "feat-2729": "feat-4077", + "feat-2742": "feat-4078", + "feat-2743": "feat-4079", + "feat-2986": "feat-4340", + "feat-2987": "feat-4341", + "feat-2989": "feat-4343", + "feat-2990": "feat-4346", + "feat-2991": "feat-4349", + "feat-2992": "feat-4350", + "feat-2993": "feat-4352", + "feat-4088": "feat-5491", + "feat-5997": "feat-7108", + + "language-91": "language-180", + + "ritual-31": "ritual-191", + + "spell-641": "spell-1413", + "spell-646": "spell-1394", + "spell-841": "spell-1107", + "spell-843": "spell-2376", + "spell-1052": "spell-1309", + "spell-1053": "spell-1306", + "spell-1054": "spell-1305", + "spell-1055": "spell-1311", + "spell-1056": "spell-1310", + "spell-1057": "spell-1307", + "spell-1058": "spell-1304", + "spell-1059": "spell-1308" + }, + "MergeSources": { + "feat-963": "feat-4519", + "feat-1167": "feat-5880", + "feat-1169": "feat-5055", + "feat-1171": "feat-4858", + + "spell-551": "spell-2003", + "spell-553": "spell-2012", + "spell-559": "spell-2417", + "spell-560": "spell-2418", + "spell-571": "spell-1975", + "spell-578": "spell-1566", + "spell-654": "spell-819" + } + } +} \ No newline at end of file diff --git a/Pf2eDataScrapper/SchemaBuilder/AbstractSchemaBuildProcessor.cs b/Pf2eDataScrapper/SchemaBuilder/AbstractSchemaBuildProcessor.cs index db2d0df..879a554 100644 --- a/Pf2eDataScrapper/SchemaBuilder/AbstractSchemaBuildProcessor.cs +++ b/Pf2eDataScrapper/SchemaBuilder/AbstractSchemaBuildProcessor.cs @@ -4,7 +4,7 @@ using System.IO; using Newtonsoft.Json.Linq; using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Importers; -using Pf2eDataScrapper.Processors; +using Pf2eDataScrapper.Processors.Definitions; namespace Pf2eDataScrapper.SchemaBuilder; diff --git a/Pf2eDataScrapper/WPF/EntityViewer/Component/EntityListControl.xaml.cs b/Pf2eDataScrapper/WPF/EntityViewer/Component/EntityListControl.xaml.cs index ef4b466..599d8ce 100644 --- a/Pf2eDataScrapper/WPF/EntityViewer/Component/EntityListControl.xaml.cs +++ b/Pf2eDataScrapper/WPF/EntityViewer/Component/EntityListControl.xaml.cs @@ -1,42 +1,15 @@ -using System.Windows; -using Pf2eDataScrapper.WPF.EntityViewer.ViewModel; - -namespace Pf2eDataScrapper.WPF.EntityViewer.Component; +namespace Pf2eDataScrapper.WPF.EntityViewer.Component; /// /// Логика взаимодействия для DbEntityListControl.xaml /// internal partial class EntityListControl : System.Windows.Controls.UserControl { - private EntityListViewModel? _viewModel; - public EntityListControl() { InitializeComponent(); } - //https://www.youtube.com/watch?v=54ZmhbpjBmg - - private void FirstButton_OnClick(object sender, RoutedEventArgs e) - { - // DataContext?.FirstPage(); - } - - private void PreviousButton_OnClick(object sender, RoutedEventArgs e) - { - //ViewModel?.PreviousPage(); - } - - private void NextButton_OnClick(object sender, RoutedEventArgs e) - { - //ViewModel?.NextPage(); - } - - private void LastButton_OnClick(object sender, RoutedEventArgs e) - { - //ViewModel?.LastPage(); - } - private void TextBox_PreviewTextInput( object sender, System.Windows.Input.TextCompositionEventArgs e diff --git a/Pf2eDataScrapper/WPF/EntityViewer/EntityForm.xaml.cs b/Pf2eDataScrapper/WPF/EntityViewer/EntityForm.xaml.cs index de08bbe..4a2c924 100644 --- a/Pf2eDataScrapper/WPF/EntityViewer/EntityForm.xaml.cs +++ b/Pf2eDataScrapper/WPF/EntityViewer/EntityForm.xaml.cs @@ -29,6 +29,8 @@ internal partial class EntityForm : Window private void Button_Click(object sender, RoutedEventArgs e) { - (Application.Current as ImportApplication)!.CurrentStage = ApplicationStage.InitialSettings; + ApplicationStateChange?.Invoke(this, ApplicationStage.InitialSettings); } + + public event ImportApplication.ApplicationStateChangeDelegate? ApplicationStateChange; } diff --git a/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureRow.cs b/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureRow.cs index f2d2b25..90deed2 100644 --- a/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureRow.cs +++ b/Pf2eDataScrapper/WPF/EntityViewer/EntityViewStructure/StructureRow.cs @@ -124,10 +124,6 @@ internal class StructureRow : INotifyPropertyChanged Field.PropertyChanged += Field_PropertyChanged; } - /// - /// - /// - /// private void Field_PropertyChanged(object? sender, PropertyChangedEventArgs e) { OnPropertyChanged(nameof(Field)); diff --git a/Pf2eDataScrapper/WPF/ProgressForm/ProgressForm.xaml.cs b/Pf2eDataScrapper/WPF/ProgressForm/ProgressForm.xaml.cs index d413045..5a63814 100644 --- a/Pf2eDataScrapper/WPF/ProgressForm/ProgressForm.xaml.cs +++ b/Pf2eDataScrapper/WPF/ProgressForm/ProgressForm.xaml.cs @@ -2,6 +2,7 @@ using System.Collections.ObjectModel; using System.Drawing; using System.Windows; +using LinqToDB.Tools; using Pf2eDataScrapper.Helpers; namespace Pf2eDataScrapper.WPF.ProgressForm; @@ -26,7 +27,6 @@ internal partial class ProgressForm : Window Progress.ProgressComplete += Progress_ProgressComplete; } - private void Progress_ProgressUpdate(ProcessProgress sender) { if (!Dispatcher.CheckAccess()) @@ -58,9 +58,10 @@ internal partial class ProgressForm : Window MessageListView.ScrollIntoView(item); } + private void Progress_ProgressComplete(ProcessProgress sender) { - (Application.Current as ImportApplication)!.CurrentStage = ApplicationStage.Viewer; + ApplicationStateChange?.Invoke(this, ApplicationStage.Viewer); } public event ImportApplication.ApplicationStateChangeDelegate? ApplicationStateChange; diff --git a/Pf2eDataScrapper/WPF/StartForm/Components/ProcessorCollectionControl.xaml.cs b/Pf2eDataScrapper/WPF/StartForm/Components/ProcessorCollectionControl.xaml.cs index 02967e8..5fad335 100644 --- a/Pf2eDataScrapper/WPF/StartForm/Components/ProcessorCollectionControl.xaml.cs +++ b/Pf2eDataScrapper/WPF/StartForm/Components/ProcessorCollectionControl.xaml.cs @@ -3,7 +3,8 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Windows; -using Pf2eDataScrapper.App; +using Pf2eDataScrapper.Processors.Attributes; +using Pf2eDataScrapper.Processors.Collection; using CheckBox = System.Windows.Controls.CheckBox; namespace Pf2eDataScrapper.WPF.StartForm.Components; @@ -61,11 +62,7 @@ internal partial class ProcessorCollectionControl : System.Windows.Controls.User Style = (Style)Resources["ElementPanelStyle"]!, }; - foreach ( - ProcessorCollectionItem item in Collection.AllItems.Where(item => - item.Group == group - ) - ) + foreach (ProcessorRecord item in Collection.AllItems.Where(item => item.Group == group)) { ItemCheckBoxes[item.Name] = new() { @@ -96,7 +93,7 @@ internal partial class ProcessorCollectionControl : System.Windows.Controls.User foreach ((string key, CheckBox? checkBox) in ItemCheckBoxes) { - ProcessorCollectionItem item = Collection[key]; + ProcessorRecord item = Collection[key]; bool isChecked = checkBox.IsChecked ?? false; if (GroupLastStats.TryGetValue(item.Group, out bool? state)) diff --git a/Pf2eDataScrapper/WPF/StartForm/StartForm.xaml.cs b/Pf2eDataScrapper/WPF/StartForm/StartForm.xaml.cs index 15e0580..fe9c9e7 100644 --- a/Pf2eDataScrapper/WPF/StartForm/StartForm.xaml.cs +++ b/Pf2eDataScrapper/WPF/StartForm/StartForm.xaml.cs @@ -1,5 +1,5 @@ using System.Windows; -using Pf2eDataScrapper.App; +using Pf2eDataScrapper.Processors.Collection; namespace Pf2eDataScrapper.WPF.StartForm; diff --git a/Pf2eModel/Migrations/20250521102908_1.Designer.cs b/Pf2eModel/Migrations/20250521155437_1.Designer.cs similarity index 99% rename from Pf2eModel/Migrations/20250521102908_1.Designer.cs rename to Pf2eModel/Migrations/20250521155437_1.Designer.cs index a237127..2525e09 100644 --- a/Pf2eModel/Migrations/20250521102908_1.Designer.cs +++ b/Pf2eModel/Migrations/20250521155437_1.Designer.cs @@ -13,7 +13,7 @@ using Pf2eModel.Model.Enum; namespace Pf2eModel.Migrations { [DbContext(typeof(Pf2eDbContext))] - [Migration("20250521102908_1")] + [Migration("20250521155437_1")] partial class _1 { /// diff --git a/Pf2eModel/Migrations/20250521102908_1.cs b/Pf2eModel/Migrations/20250521155437_1.cs similarity index 100% rename from Pf2eModel/Migrations/20250521102908_1.cs rename to Pf2eModel/Migrations/20250521155437_1.cs