diff --git a/Documentation/Pf2eDataScrapper/EntityView.Context.md b/Documentation/Pf2eDataScrapper/EntityView.Context.md
new file mode 100644
index 0000000..71335cc
--- /dev/null
+++ b/Documentation/Pf2eDataScrapper/EntityView.Context.md
@@ -0,0 +1,13 @@
+#### [Pf2eDataScrapper](index.md 'index')
+### [Pf2eDataScrapper\.Helpers](Pf2eDataScrapper.Helpers.md 'Pf2eDataScrapper\.Helpers').[EntityView](EntityView.md 'Pf2eDataScrapper\.Helpers\.EntityView')
+
+## EntityView\.Context Property
+
+Контекст базы данных, используемый для получения сущностей\.
+
+```csharp
+private Pf2eModel.Pf2eDbContext Context { private get; }
+```
+
+#### Property Value
+[Pf2eModel\.Pf2eDbContext](https://docs.microsoft.com/en-us/dotnet/api/Pf2eModel.Pf2eDbContext 'Pf2eModel\.Pf2eDbContext')
\ No newline at end of file
diff --git a/Documentation/Pf2eDataScrapper/EntityView.Entity.md b/Documentation/Pf2eDataScrapper/EntityView.Entity.md
index 5062cff..468479f 100644
--- a/Documentation/Pf2eDataScrapper/EntityView.Entity.md
+++ b/Documentation/Pf2eDataScrapper/EntityView.Entity.md
@@ -6,7 +6,7 @@
Корневая сущность\.
```csharp
-public Pf2eModel.Model.Base.Entity? Entity { get; }
+public Pf2eModel.Model.Base.Entity Entity { get; }
```
#### Property Value
diff --git a/Documentation/Pf2eDataScrapper/EntityView.EntityView(Pf2eDbContext,EntityType,int).md b/Documentation/Pf2eDataScrapper/EntityView.EntityView(Pf2eDbContext,EntityType,int).md
deleted file mode 100644
index e8904ca..0000000
--- a/Documentation/Pf2eDataScrapper/EntityView.EntityView(Pf2eDbContext,EntityType,int).md
+++ /dev/null
@@ -1,29 +0,0 @@
-#### [Pf2eDataScrapper](index.md 'index')
-### [Pf2eDataScrapper\.Helpers](Pf2eDataScrapper.Helpers.md 'Pf2eDataScrapper\.Helpers').[EntityView](EntityView.md 'Pf2eDataScrapper\.Helpers\.EntityView')
-
-## EntityView\(Pf2eDbContext, EntityType, int\) Constructor
-
-Конструктор класса, который получает сущность из базы данных и заполняет её данными\.
-
-```csharp
-public EntityView(Pf2eModel.Pf2eDbContext context, Pf2eModel.Model.Enum.EntityType type, int id);
-```
-#### Parameters
-
-
-
-`context` [Pf2eModel\.Pf2eDbContext](https://docs.microsoft.com/en-us/dotnet/api/Pf2eModel.Pf2eDbContext 'Pf2eModel\.Pf2eDbContext')
-
-Контекст базы данных\.
-
-
-
-`type` [Pf2eModel\.Model\.Enum\.EntityType](https://docs.microsoft.com/en-us/dotnet/api/Pf2eModel.Model.Enum.EntityType 'Pf2eModel\.Model\.Enum\.EntityType')
-
-Тип запрашиваемой сущности\.
-
-
-
-`id` [System\.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System\.Int32')
-
-Идентификатор запрашиваемой сущности\.
\ No newline at end of file
diff --git a/Documentation/Pf2eDataScrapper/EntityView.EntityView.md b/Documentation/Pf2eDataScrapper/EntityView.EntityView.md
new file mode 100644
index 0000000..c587f63
--- /dev/null
+++ b/Documentation/Pf2eDataScrapper/EntityView.EntityView.md
@@ -0,0 +1,61 @@
+#### [Pf2eDataScrapper](index.md 'index')
+### [Pf2eDataScrapper\.Helpers](Pf2eDataScrapper.Helpers.md 'Pf2eDataScrapper\.Helpers').[EntityView](EntityView.md 'Pf2eDataScrapper\.Helpers\.EntityView')
+
+## EntityView Constructors
+
+| Overloads | |
+| :--- | :--- |
+| [EntityView\(Pf2eDbContext, Entity\)](EntityView.EntityView.md#Pf2eDataScrapper.Helpers.EntityView.EntityView(Pf2eModel.Pf2eDbContext,Pf2eModel.Model.Base.Entity) 'Pf2eDataScrapper\.Helpers\.EntityView\.EntityView\(Pf2eModel\.Pf2eDbContext, Pf2eModel\.Model\.Base\.Entity\)') | Конструктор класса, который получает сущность из базы данных по переданной сущности и заполняет её данными\. |
+| [EntityView\(Pf2eDbContext, EntityType, int\)](EntityView.EntityView.md#Pf2eDataScrapper.Helpers.EntityView.EntityView(Pf2eModel.Pf2eDbContext,Pf2eModel.Model.Enum.EntityType,int) 'Pf2eDataScrapper\.Helpers\.EntityView\.EntityView\(Pf2eModel\.Pf2eDbContext, Pf2eModel\.Model\.Enum\.EntityType, int\)') | Конструктор класса, который получает сущность из базы данных по типу и идентификатору и заполняет её данными\. |
+
+
+
+## EntityView\(Pf2eDbContext, Entity\) Constructor
+
+Конструктор класса, который получает сущность из базы данных по переданной сущности и заполняет её данными\.
+
+```csharp
+public EntityView(Pf2eModel.Pf2eDbContext context, Pf2eModel.Model.Base.Entity entity);
+```
+#### Parameters
+
+
+
+`context` [Pf2eModel\.Pf2eDbContext](https://docs.microsoft.com/en-us/dotnet/api/Pf2eModel.Pf2eDbContext 'Pf2eModel\.Pf2eDbContext')
+
+Контекст базы данных\.
+
+
+
+`entity` [Pf2eModel\.Model\.Base\.Entity](https://docs.microsoft.com/en-us/dotnet/api/Pf2eModel.Model.Base.Entity 'Pf2eModel\.Model\.Base\.Entity')
+
+Сущность, которую нужно обработать\.
+
+
+
+## EntityView\(Pf2eDbContext, EntityType, int\) Constructor
+
+Конструктор класса, который получает сущность из базы данных по типу и идентификатору и заполняет её данными\.
+
+```csharp
+public EntityView(Pf2eModel.Pf2eDbContext context, Pf2eModel.Model.Enum.EntityType type, int id);
+```
+#### Parameters
+
+
+
+`context` [Pf2eModel\.Pf2eDbContext](https://docs.microsoft.com/en-us/dotnet/api/Pf2eModel.Pf2eDbContext 'Pf2eModel\.Pf2eDbContext')
+
+Контекст базы данных\.
+
+
+
+`type` [Pf2eModel\.Model\.Enum\.EntityType](https://docs.microsoft.com/en-us/dotnet/api/Pf2eModel.Model.Enum.EntityType 'Pf2eModel\.Model\.Enum\.EntityType')
+
+Тип запрашиваемой сущности\.
+
+
+
+`id` [System\.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System\.Int32')
+
+Идентификатор запрашиваемой сущности\.
\ No newline at end of file
diff --git a/Documentation/Pf2eDataScrapper/EntityView.GetEntity(EntityType,int).md b/Documentation/Pf2eDataScrapper/EntityView.GetEntity(EntityType,int).md
new file mode 100644
index 0000000..422aada
--- /dev/null
+++ b/Documentation/Pf2eDataScrapper/EntityView.GetEntity(EntityType,int).md
@@ -0,0 +1,27 @@
+#### [Pf2eDataScrapper](index.md 'index')
+### [Pf2eDataScrapper\.Helpers](Pf2eDataScrapper.Helpers.md 'Pf2eDataScrapper\.Helpers').[EntityView](EntityView.md 'Pf2eDataScrapper\.Helpers\.EntityView')
+
+## EntityView\.GetEntity\(EntityType, int\) Method
+
+Получает сущность из базы данных по типу и идентификатору\.
+
+```csharp
+private Pf2eModel.Model.Base.Entity GetEntity(Pf2eModel.Model.Enum.EntityType type, int id);
+```
+#### Parameters
+
+
+
+`type` [Pf2eModel\.Model\.Enum\.EntityType](https://docs.microsoft.com/en-us/dotnet/api/Pf2eModel.Model.Enum.EntityType 'Pf2eModel\.Model\.Enum\.EntityType')
+
+Тип сущности\.
+
+
+
+`id` [System\.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System\.Int32')
+
+Идентификатор сущности\.
+
+#### Returns
+[Pf2eModel\.Model\.Base\.Entity](https://docs.microsoft.com/en-us/dotnet/api/Pf2eModel.Model.Base.Entity 'Pf2eModel\.Model\.Base\.Entity')
+Сущность, соответствующая указанному типу и идентификатору\.
\ No newline at end of file
diff --git a/Documentation/Pf2eDataScrapper/EntityView.GetSubEntity(EntityType,int).md b/Documentation/Pf2eDataScrapper/EntityView.GetSubEntity(EntityType,int).md
new file mode 100644
index 0000000..1ac1ba8
--- /dev/null
+++ b/Documentation/Pf2eDataScrapper/EntityView.GetSubEntity(EntityType,int).md
@@ -0,0 +1,27 @@
+#### [Pf2eDataScrapper](index.md 'index')
+### [Pf2eDataScrapper\.Helpers](Pf2eDataScrapper.Helpers.md 'Pf2eDataScrapper\.Helpers').[EntityView](EntityView.md 'Pf2eDataScrapper\.Helpers\.EntityView')
+
+## EntityView\.GetSubEntity\(EntityType, int\) Method
+
+Получает подчинённую сущность по типу и идентификатору\.
+
+```csharp
+private Pf2eModel.Model.IEntity? GetSubEntity(Pf2eModel.Model.Enum.EntityType type, int id);
+```
+#### Parameters
+
+
+
+`type` [Pf2eModel\.Model\.Enum\.EntityType](https://docs.microsoft.com/en-us/dotnet/api/Pf2eModel.Model.Enum.EntityType 'Pf2eModel\.Model\.Enum\.EntityType')
+
+Тип сущности\.
+
+
+
+`id` [System\.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System\.Int32')
+
+Идентификатор сущности\.
+
+#### Returns
+[Pf2eModel\.Model\.IEntity](https://docs.microsoft.com/en-us/dotnet/api/Pf2eModel.Model.IEntity 'Pf2eModel\.Model\.IEntity')
+Подчинённая сущность, соответствующая указанному типу и идентификатору\.
\ No newline at end of file
diff --git a/Documentation/Pf2eDataScrapper/EntityView.md b/Documentation/Pf2eDataScrapper/EntityView.md
index b11a9c2..20e3413 100644
--- a/Documentation/Pf2eDataScrapper/EntityView.md
+++ b/Documentation/Pf2eDataScrapper/EntityView.md
@@ -13,7 +13,8 @@ Inheritance [System\.Object](https://docs.microsoft.com/en-us/dotnet/api/System.
| Constructors | |
| :--- | :--- |
-| [EntityView\(Pf2eDbContext, EntityType, int\)](EntityView.EntityView(Pf2eDbContext,EntityType,int).md 'Pf2eDataScrapper\.Helpers\.EntityView\.EntityView\(Pf2eModel\.Pf2eDbContext, Pf2eModel\.Model\.Enum\.EntityType, int\)') | Конструктор класса, который получает сущность из базы данных и заполняет её данными\. |
+| [EntityView\(Pf2eDbContext, Entity\)](EntityView.EntityView.md#Pf2eDataScrapper.Helpers.EntityView.EntityView(Pf2eModel.Pf2eDbContext,Pf2eModel.Model.Base.Entity) 'Pf2eDataScrapper\.Helpers\.EntityView\.EntityView\(Pf2eModel\.Pf2eDbContext, Pf2eModel\.Model\.Base\.Entity\)') | Конструктор класса, который получает сущность из базы данных по переданной сущности и заполняет её данными\. |
+| [EntityView\(Pf2eDbContext, EntityType, int\)](EntityView.EntityView.md#Pf2eDataScrapper.Helpers.EntityView.EntityView(Pf2eModel.Pf2eDbContext,Pf2eModel.Model.Enum.EntityType,int) 'Pf2eDataScrapper\.Helpers\.EntityView\.EntityView\(Pf2eModel\.Pf2eDbContext, Pf2eModel\.Model\.Enum\.EntityType, int\)') | Конструктор класса, который получает сущность из базы данных по типу и идентификатору и заполняет её данными\. |
| Fields | |
| :--- | :--- |
@@ -21,5 +22,11 @@ Inheritance [System\.Object](https://docs.microsoft.com/en-us/dotnet/api/System.
| Properties | |
| :--- | :--- |
+| [Context](EntityView.Context.md 'Pf2eDataScrapper\.Helpers\.EntityView\.Context') | Контекст базы данных, используемый для получения сущностей\. |
| [Entity](EntityView.Entity.md 'Pf2eDataScrapper\.Helpers\.EntityView\.Entity') | Корневая сущность\. |
| [SubEntity](EntityView.SubEntity.md 'Pf2eDataScrapper\.Helpers\.EntityView\.SubEntity') | Основная сущность\. |
+
+| Methods | |
+| :--- | :--- |
+| [GetEntity\(EntityType, int\)](EntityView.GetEntity(EntityType,int).md 'Pf2eDataScrapper\.Helpers\.EntityView\.GetEntity\(Pf2eModel\.Model\.Enum\.EntityType, int\)') | Получает сущность из базы данных по типу и идентификатору\. |
+| [GetSubEntity\(EntityType, int\)](EntityView.GetSubEntity(EntityType,int).md 'Pf2eDataScrapper\.Helpers\.EntityView\.GetSubEntity\(Pf2eModel\.Model\.Enum\.EntityType, int\)') | Получает подчинённую сущность по типу и идентификатору\. |
diff --git a/Documentation/Pf2eDataScrapper/FoundryGlobals.FoundryTarget.md b/Documentation/Pf2eDataScrapper/FoundryGlobals.FoundryTarget.md
new file mode 100644
index 0000000..c80d82f
--- /dev/null
+++ b/Documentation/Pf2eDataScrapper/FoundryGlobals.FoundryTarget.md
@@ -0,0 +1,13 @@
+#### [Pf2eDataScrapper](index.md 'index')
+### [Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Helpers](Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers.md 'Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Helpers').[FoundryGlobals](FoundryGlobals.md 'Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Helpers\.FoundryGlobals')
+
+## FoundryGlobals\.FoundryTarget Property
+
+Цель внешних ссылок для Foundry En\.
+
+```csharp
+public Pf2eModel.Model.Base.Targets.ExternalTarget FoundryTarget { get; set; }
+```
+
+#### Property Value
+[Pf2eModel\.Model\.Base\.Targets\.ExternalTarget](https://docs.microsoft.com/en-us/dotnet/api/Pf2eModel.Model.Base.Targets.ExternalTarget 'Pf2eModel\.Model\.Base\.Targets\.ExternalTarget')
\ No newline at end of file
diff --git a/Documentation/Pf2eDataScrapper/FoundryGlobals.md b/Documentation/Pf2eDataScrapper/FoundryGlobals.md
new file mode 100644
index 0000000..08b90e2
--- /dev/null
+++ b/Documentation/Pf2eDataScrapper/FoundryGlobals.md
@@ -0,0 +1,16 @@
+#### [Pf2eDataScrapper](index.md 'index')
+### [Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Helpers](Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers.md 'Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Helpers')
+
+## FoundryGlobals Class
+
+Глобальные константы и утилиты для импорта данных в формате Foundry En\.
+
+```csharp
+internal class FoundryGlobals
+```
+
+Inheritance [System\.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System\.Object') 🡒 FoundryGlobals
+
+| Properties | |
+| :--- | :--- |
+| [FoundryTarget](FoundryGlobals.FoundryTarget.md 'Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Helpers\.FoundryGlobals\.FoundryTarget') | Цель внешних ссылок для Foundry En\. |
diff --git a/Documentation/Pf2eDataScrapper/Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers.md b/Documentation/Pf2eDataScrapper/Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers.md
new file mode 100644
index 0000000..d821425
--- /dev/null
+++ b/Documentation/Pf2eDataScrapper/Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers.md
@@ -0,0 +1,7 @@
+#### [Pf2eDataScrapper](index.md 'index')
+
+## Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Helpers Namespace
+
+| Classes | |
+| :--- | :--- |
+| [FoundryGlobals](FoundryGlobals.md 'Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Helpers\.FoundryGlobals') | Глобальные константы и утилиты для импорта данных в формате Foundry En\. |
diff --git a/Documentation/Pf2eDataScrapper/index.md b/Documentation/Pf2eDataScrapper/index.md
index 70d5df4..7879d1f 100644
--- a/Documentation/Pf2eDataScrapper/index.md
+++ b/Documentation/Pf2eDataScrapper/index.md
@@ -17,6 +17,7 @@
| [Pf2eDataScrapper\.Importers\.Implementations\.Aonprd\.Processors\.Types\.Rules](Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Types.Rules.md 'Pf2eDataScrapper\.Importers\.Implementations\.Aonprd\.Processors\.Types\.Rules') | Обработчики правил с сайта [Archives of Nethys Pathfinder 2e](https://aonprd.com/ 'https://aonprd\.com/')\. |
| [Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn](Pf2eDataScrapper.Importers.Implementations.FoundryEn.md 'Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn') | Импортёр данных из модуля [pf2e](https://github.com/foundryvtt/pf2e 'https://github\.com/foundryvtt/pf2e') для FoundryVTT\. |
| [Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Compendium](Pf2eDataScrapper.Importers.Implementations.FoundryEn.Compendium.md 'Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Compendium') | Компендиум данных из модуля [pf2e](https://github.com/foundryvtt/pf2e 'https://github\.com/foundryvtt/pf2e') для FoundryVTT\. |
+| [Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Helpers](Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers.md 'Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Helpers') | |
| [Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Processors\.Preparation](Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors.Preparation.md 'Pf2eDataScrapper\.Importers\.Implementations\.FoundryEn\.Processors\.Preparation') | Обработчики для подготовки данных из модуля [pf2e](https://github.com/foundryvtt/pf2e 'https://github\.com/foundryvtt/pf2e') для FoundryVTT\. |
| [Pf2eDataScrapper\.Importers\.Repositories](Pf2eDataScrapper.Importers.Repositories.md 'Pf2eDataScrapper\.Importers\.Repositories') | Общее описание репозиториев для хранения данных, которые используются в импортёрах и процессорах\. |
| [Pf2eDataScrapper\.Processors](Pf2eDataScrapper.Processors.md 'Pf2eDataScrapper\.Processors') | Общее описание обработчиков данных\. |
diff --git a/Documentation/Pf2eModel/ActionCategory.md b/Documentation/Pf2eModel/ActionCategory.md
index 5d7feb2..f51c32d 100644
--- a/Documentation/Pf2eModel/ActionCategory.md
+++ b/Documentation/Pf2eModel/ActionCategory.md
@@ -40,56 +40,38 @@ public enum ActionCategory
Действие классовой черты\.
-
-
-`Offensive` 5
-
-Действие атаки\.
-
-
-
-`Defensive` 6
-
-Действие защиты\.
-
-
-
-`Interaction` 7
-
-Действие взаимодействия\.
-
-`Familiar` 8
+`Familiar` 5
Действие фамильяра\.
-`ArmyTactic` 9
+`ArmyTactic` 6
Действие тактики армии\.
-`ArmyWarAction` 10
+`ArmyWarAction` 7
Действие войны армии\.
-`KingdomActivity` 11
+`KingdomActivity` 8
Активность королевства\.
-`KingdomFeat` 12
+`KingdomFeat` 9
Действие черты королевства\.
-`KingdomFeature` 13
+`KingdomFeature` 10
Действие особенности королевства\.
\ No newline at end of file
diff --git a/Pf2eDataScrapper/Helpers/EntityView.cs b/Pf2eDataScrapper/Helpers/EntityView.cs
index a24964b..4081311 100644
--- a/Pf2eDataScrapper/Helpers/EntityView.cs
+++ b/Pf2eDataScrapper/Helpers/EntityView.cs
@@ -18,7 +18,7 @@ public class EntityView
///
/// Корневая сущность.
///
- public Entity? Entity { get; }
+ public Entity Entity { get; }
///
/// Основная сущность.
@@ -26,34 +26,65 @@ public class EntityView
public IEntity? SubEntity { get; }
///
- /// Конструктор класса, который получает сущность из базы данных и заполняет её данными.
+ /// Контекст базы данных, используемый для получения сущностей.
+ ///
+ private Pf2eDbContext Context { get; }
+
+ ///
+ /// Конструктор класса, который получает сущность из базы данных по типу и идентификатору и заполняет её данными.
///
/// Контекст базы данных.
/// Тип запрашиваемой сущности.
/// Идентификатор запрашиваемой сущности.
public EntityView(Pf2eDbContext context, EntityType type, int id)
+ {
+ Context = context;
+ Entity = GetEntity(type, id);
+ SubEntity = GetSubEntity(type, id);
+ }
+
+ ///
+ /// Конструктор класса, который получает сущность из базы данных по переданной сущности и заполняет её данными.
+ ///
+ /// Контекст базы данных.
+ /// Сущность, которую нужно обработать.
+ public EntityView(Pf2eDbContext context, Entity entity)
+ {
+ Context = context;
+ Entity = entity;
+ SubEntity = GetSubEntity(entity.Type, entity.Id);
+ }
+
+ ///
+ /// Получает сущность из базы данных по типу и идентификатору.
+ ///
+ /// Тип сущности.
+ /// Идентификатор сущности.
+ /// Сущность, соответствующая указанному типу и идентификатору.
+ private Entity GetEntity(EntityType type, int id) =>
+ Context
+ .Entities.Where(e => e.Id == id && e.Type == type)
+ .Include(e => e.Sources)
+ .ThenInclude(s => s.Source)
+ .Include(e => e.Keywords)
+ .Include(e => e.Externals)
+ .ThenInclude(x => x.Target)
+ .Include(e => e.Traits)
+ .ThenInclude(t => t.Entity)
+ .FirstOrDefault() ?? throw new("Entity is null");
+
+ ///
+ /// Получает подчинённую сущность по типу и идентификатору.
+ ///
+ /// Тип сущности.
+ /// Идентификатор сущности.
+ /// Подчинённая сущность, соответствующая указанному типу и идентификатору.
+ private IEntity? GetSubEntity(EntityType type, int id)
{
Getter? getter = _getters.FirstOrDefault(g => g.Type == type);
-
- Entity fullEntity =
- context
- .Entities.Where(e => e.Id == id && e.Type == type)
- .Include(e => e.Sources)
- .ThenInclude(s => s.Source)
- .Include(e => e.Keywords)
- .Include(e => e.Externals)
- .ThenInclude(x => x.Target)
- .Include(e => e.Traits)
- .ThenInclude(t => t.Entity)
- .FirstOrDefault() ?? throw new("Entity is null");
-
- IEntity? subEntity =
- (getter != null)
- ? getter.Get(id, context)
- : (IEntity?)context.Find(EntityOfTypeAttribute.Resolve(fullEntity), id);
-
- Entity = fullEntity;
- SubEntity = subEntity;
+ return (getter != null)
+ ? getter.Get(id, this.Context)
+ : (IEntity?)Context.Find(EntityOfTypeAttribute.Resolve(Entity), id);
}
///
diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Helpers/FoundryGlobals.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Helpers/FoundryGlobals.cs
new file mode 100644
index 0000000..c2a41bc
--- /dev/null
+++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Helpers/FoundryGlobals.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Pf2eModel.Model.Base.Source;
+using Pf2eModel.Model.Base.Targets;
+
+namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers;
+
+///
+/// Глобальные константы и утилиты для импорта данных в формате Foundry En.
+///
+internal class FoundryGlobals
+{
+ ///
+ /// Цель внешних ссылок для Foundry En.
+ ///
+ public ExternalTarget FoundryTarget { get; set; } = null!;
+}
diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ActionProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ActionProcessor.cs
index 34e192b..6c25715 100644
--- a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ActionProcessor.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ActionProcessor.cs
@@ -1,5 +1,6 @@
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.Helpers;
+using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers;
using Pf2eDataScrapper.Processors;
using Pf2eDataScrapper.Processors.Attributes;
using Pf2eDataScrapper.Processors.Collection;
@@ -20,26 +21,20 @@ namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors.Entiti
internal class ActionProcessor(
DatabaseHelper databaseHelper,
Pf2eDbContext context,
+ FoundryGlobals globals,
ProcessorInput input
-) : FoundryEnAbstractProcessor(databaseHelper, context, input)
+)
+ : FoundryEnAbstractProcessor(
+ databaseHelper,
+ context,
+ globals,
+ input
+ )
{
public override EntityType Type => EntityType.Action;
- public override Pf2eModel.Model.Structure.Action Object { get; } = new();
-
public override void Process()
{
base.Process();
- /*
- Object.Type = EnumRequired("system.actionType.value");
- Object.Category = EnumOptional("system.category", ActionCategory.Unknown);
- Object.Actions = GetOptional("system.actions.value");
- Object.DeathNote = GetOptional("system.deathNote");
- */
- JObject extra = new() { { "selfEffect", Input.Input.SelectToken("system.selfEffect") } };
-
- Object.Extra = extra.ToString(Newtonsoft.Json.Formatting.None);
-
- Context.Actions.Add(Object);
}
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ConditionProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ConditionProcessor.cs
index 5cf90a3..7af2298 100644
--- a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ConditionProcessor.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ConditionProcessor.cs
@@ -1,5 +1,6 @@
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.Helpers;
+using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers;
using Pf2eDataScrapper.Processors;
using Pf2eDataScrapper.Processors.Attributes;
using Pf2eDataScrapper.Processors.Collection;
@@ -21,17 +22,16 @@ namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors.Entiti
internal class ConditionProcessor(
DatabaseHelper databaseHelper,
Pf2eDbContext context,
+ FoundryGlobals globals,
ProcessorInput input
-) : FoundryEnAbstractProcessor(databaseHelper, context, input)
+) : FoundryEnAbstractProcessor(databaseHelper, context, globals, input)
{
public override EntityType Type => EntityType.Condition;
- public override Condition Object { get; } = new();
-
public override void Process()
{
base.Process();
-
+ /*
JObject extra = new()
{
{ "duration", Input.Input.SelectToken("system.duration") },
@@ -44,5 +44,6 @@ internal class ConditionProcessor(
Object.Group = Input.EnumOptional("system.group", ConditionGroup.Unknown);
Context.Conditions.Add(Object);
+ */
}
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/FoundryEnAbstractProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/FoundryEnAbstractProcessor.cs
index 4459b3b..d6bdc60 100644
--- a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/FoundryEnAbstractProcessor.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/FoundryEnAbstractProcessor.cs
@@ -3,9 +3,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
+using System.Windows.Documents;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.Helpers;
+using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers;
using Pf2eDataScrapper.Processors;
using Pf2eDataScrapper.Processors.Definitions;
using Pf2eModel;
@@ -19,86 +21,66 @@ using Pf2eModel.Model.Structure;
namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors;
-internal abstract class FoundryEnAbstractProcessor(
+internal abstract class FoundryEnAbstractProcessor(
DatabaseHelper databaseHelper,
Pf2eDbContext context,
+ FoundryGlobals globals,
ProcessorInput input
) : AbstractInputProcessor(input)
+ where TEntity : class, IEntity?
{
protected DatabaseHelper Helper { get; } = databaseHelper;
public Pf2eDbContext Context { get; } = context;
- public Entity Entity { get; set; } = new();
+ public FoundryGlobals Globals { get; } = globals;
public abstract EntityType Type { get; }
- public abstract IEntity Object { get; }
+ public EntityView View { get; private set; } = null!;
+
+ public Entity Entity => View.Entity;
+
+ public TEntity Object =>
+ View.SubEntity as TEntity
+ ?? throw new InvalidOperationException(
+ $"Сущность {View.SubEntity} некорректного типа, ожидался тип {typeof(TEntity)}."
+ );
+
+ public virtual void ResolveEntity()
+ {
+ string name = Input.GetRequired("name");
+
+ try
+ {
+ int id = Context
+ .Entities.Include(e => e.Name)
+ .Where(e => Pf2eDbContext.LocaleSearch(e.Name, name) && e.Type == Type)
+ .Select(e => e.Id)
+ .FirstOrDefault();
+
+ View = new EntityView(Context, Type, id);
+ }
+ catch (Exception ex)
+ {
+ throw new SkipItemException(name, ex.Message);
+ }
+ }
public override void Process()
{
- Entity.Id = Helper.NextEntityId;
- Entity.Type = Type;
-
- Entity.Name[LocaleType.English] = Input.GetRequired("name");
- Entity.Img = Input.GetRequired("img");
- Entity.Description = Input.GetRequired("system.description.value");
-
- Entity.IsTranslated = false;
- Entity.IsChecked = false;
-
- Entity.Slug = Helper.GenerateSlug(Entity.Name[LocaleType.English]);
- Entity.Rarity = Input.EnumOptional("system.traits.rarity", EntityRarity.Common);
-
- Object.Id = Entity.Id;
-
- Context.Entities.Add(Entity);
-
- // Alias
- /*
- EntityAlias alias = new()
- {
- Type = LocaleType.English,
- Alias = Entity.Group,
- LegacyId = Entity.Id,
- Entity = Entity
- };
- Context.EntityAliases.Add(alias);
- */
- // Source
- EntitySource source = new()
- {
- Entity = Entity,
-
- Source = GetSource(Input.GetRequired("system.publication.title")),
-
- Suffix = "",
- IsRemaster = Input.GetRequired("system.publication.remaster"),
- };
- Context.EntitySources.Add(source);
+ ResolveEntity();
// External
EntityExternal external = new()
{
Entity = Entity,
- Target = GetTarget(),
+ Target = Globals.FoundryTarget,
+ ExternalId = Input.GetOptional("_id"),
Suffix = Input.GetRequired("_id"),
- Md5 = Md5(Input.Input.ToString()),
+ Md5 = Input.Md5(),
};
Context.EntityExternals.Add(external);
-
- // Traits
- JToken? traitsJson = Input.Input.SelectToken("system.traits.value");
-
- if (traitsJson?.Type != JTokenType.Array)
- {
- throw new Exception("system.traits.value is expected to be an array");
- }
-
- foreach (Trait trait in GetTraits(traitsJson.ToArray().Select(jToken => jToken.ToString())))
- {
- Entity.Traits.Add(trait);
- }
}
public override void Save()
@@ -120,65 +102,4 @@ internal abstract class FoundryEnAbstractProcessor(
Context.Sources.Add(source);
return source;
}
-
- protected ExternalTarget GetTarget()
- {
- const string name = "pf2e - Foundry module";
-
- ExternalTarget? target = Context.ExternalTargets.FirstOrDefault(s => s.Name == name);
-
- if (target != null)
- {
- return target;
- }
-
- target = new()
- {
- Name = "pf2e - Foundry module",
- Icon = "",
- Prefix = "https://github.com/foundryvtt/pf2e",
- };
-
- Context.ExternalTargets.Add(target);
- return target;
- }
-
- protected IEnumerable GetTraits(IEnumerable names)
- {
- List result = Context
- .Traits.Include(t => t.Entity)
- .ThenInclude(e => e.Name)
- // ReSharper disable once EntityFramework.UnsupportedServerSideFunctionCall
- .Where(t => Pf2eDbContext.LocaleSearchArray(t.Entity.Name, names))
- .ToList();
-
- /*
- foreach (string name in names)
- {
- if (result.Any(t => t.Entity.Group.Contains(name)))
- {
- continue;
- }
- Trait trait = new()
- {
- Group = name,
- Slug = name,
- Type = TraitType.Regular,
- Description = "",
- };
- Context.Traits.Add(trait);
- result.Add(trait);
- }
- */
-
- return result;
- }
-
- public static string Md5(string input, bool isLowercase = false)
- {
- using MD5 md5 = MD5.Create();
- byte[] byteHash = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
- string hash = BitConverter.ToString(byteHash).Replace("-", "");
- return isLowercase ? hash.ToLower() : hash;
- }
}
diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/ExternalProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/ExternalProcessor.cs
new file mode 100644
index 0000000..874ea31
--- /dev/null
+++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Preparation/ExternalProcessor.cs
@@ -0,0 +1,40 @@
+using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
+using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers;
+using Pf2eDataScrapper.Processors.Attributes;
+using Pf2eDataScrapper.Processors.Definitions;
+using Pf2eModel;
+using Pf2eModel.Model.Base.Targets;
+
+namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors.Preparation;
+
+[Processor(
+ "foundry-en:external",
+ Description = "Создание цели внешних ссылок",
+ Group = ProcessorGroupEnum.FoundryEnPreparation
+)]
+[ProcessorDependencies(["foundry-en:repository"])]
+internal class ExternalProcessor(FoundryGlobals globals) : AbstractSimpleProcessor
+{
+ public Pf2eDbContext Context { get; } = new();
+ public FoundryGlobals Globals { get; } = globals;
+
+ public ExternalTarget FoundryTarget = null!;
+
+ public override void Process()
+ {
+ FoundryTarget = new()
+ {
+ Name = FoundryEnImporter.TargetName,
+ Icon = "http://www.google.com/s2/favicons?domain=foundryvtt.com",
+ Prefix = "",
+ };
+ }
+
+ public override void Save()
+ {
+ Context.ExternalTargets.Add(FoundryTarget);
+ Context.SaveChanges();
+
+ Globals.FoundryTarget = FoundryTarget;
+ }
+}
diff --git a/Pf2eModel/Model/Enum/ActionCategory.cs b/Pf2eModel/Model/Enum/ActionCategory.cs
index 5d69681..a57e1bd 100644
--- a/Pf2eModel/Model/Enum/ActionCategory.cs
+++ b/Pf2eModel/Model/Enum/ActionCategory.cs
@@ -37,24 +37,6 @@ public enum ActionCategory
[PgName("class-feat")]
ClassFeat,
- ///
- /// Действие атаки.
- ///
- [PgName("offensive")]
- Offensive,
-
- ///
- /// Действие защиты.
- ///
- [PgName("defensive")]
- Defensive,
-
- ///
- /// Действие взаимодействия.
- ///
- [PgName("interaction")]
- Interaction,
-
///
/// Действие фамильяра.
///