Попытки подружить источники...
This commit is contained in:
+15
-2
@@ -36,9 +36,16 @@ internal abstract class AbstractEntityProcessor(
|
|||||||
AonprdBuilderGlobals globals
|
AonprdBuilderGlobals globals
|
||||||
) : AbstractInputProcessor(input)
|
) : AbstractInputProcessor(input)
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc cref="Pf2eDbContext"/>
|
||||||
public Pf2eDbContext Context { get; } = new();
|
public Pf2eDbContext Context { get; } = new();
|
||||||
|
|
||||||
|
/// <inheritdoc cref="StringHelper"/>
|
||||||
public StringHelper StringHelper { get; } = stringHelper;
|
public StringHelper StringHelper { get; } = stringHelper;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="DatabaseHelper"/>
|
||||||
public DatabaseHelper Helper { get; } = helper;
|
public DatabaseHelper Helper { get; } = helper;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="AonprdBuilderGlobals"/>
|
||||||
public AonprdBuilderGlobals Globals { get; } = globals;
|
public AonprdBuilderGlobals Globals { get; } = globals;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -86,7 +93,7 @@ internal abstract class AbstractEntityProcessor(
|
|||||||
{
|
{
|
||||||
if (Globals.MergeSources.ContainsKey(Input.GetRequired<string>("id")))
|
if (Globals.MergeSources.ContainsKey(Input.GetRequired<string>("id")))
|
||||||
{
|
{
|
||||||
throw new SkipItemException(Input.GetRequired<string>("name"), "помечено на слияние.");
|
throw new SkipItemException(GetEntityName(), "помечено на слияние.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,6 +152,12 @@ internal abstract class AbstractEntityProcessor(
|
|||||||
|
|
||||||
#region "Генерация сущности"
|
#region "Генерация сущности"
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получает имя сущности из входных данных.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Имя сущности.</returns>
|
||||||
|
protected virtual string GetEntityName() => Input.GetRequired<string>("name");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Генерация основных полей корневой сущности.
|
/// Генерация основных полей корневой сущности.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -156,7 +169,7 @@ internal abstract class AbstractEntityProcessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Entity.Type = Type;
|
Entity.Type = Type;
|
||||||
Entity.Name[LocaleType.English] = Input.GetRequired<string>("name");
|
Entity.Name[LocaleType.English] = GetEntityName();
|
||||||
Entity.Img = "";
|
Entity.Img = "";
|
||||||
Entity.Description = GetDescription();
|
Entity.Description = GetDescription();
|
||||||
Entity.Rarity = Input.EnumOptional("rarity", EntityRarity.Common);
|
Entity.Rarity = Input.EnumOptional("rarity", EntityRarity.Common);
|
||||||
|
|||||||
+2
-4
@@ -1,9 +1,7 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
using Pf2eDataScrapper.Helpers;
|
||||||
using Pf2eDataScrapper.Helpers;
|
|
||||||
using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers;
|
using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers;
|
||||||
using Pf2eDataScrapper.Processors;
|
using Pf2eDataScrapper.Processors;
|
||||||
using Pf2eDataScrapper.Processors.Attributes;
|
using Pf2eDataScrapper.Processors.Attributes;
|
||||||
using Pf2eDataScrapper.Processors.Collection;
|
|
||||||
using Pf2eModel;
|
using Pf2eModel;
|
||||||
using Pf2eModel.Model.Enum;
|
using Pf2eModel.Model.Enum;
|
||||||
|
|
||||||
@@ -17,7 +15,7 @@ namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors.Entiti
|
|||||||
Group = ProcessorGroupEnum.FoundryEnEntities,
|
Group = ProcessorGroupEnum.FoundryEnEntities,
|
||||||
Active = false
|
Active = false
|
||||||
)]
|
)]
|
||||||
[ProcessorDependencies(["foundry-en:compendium"])]
|
[ProcessorDependencies(["foundry-en:compendium", "foundry-en:external"])]
|
||||||
internal class ActionProcessor(
|
internal class ActionProcessor(
|
||||||
DatabaseHelper databaseHelper,
|
DatabaseHelper databaseHelper,
|
||||||
Pf2eDbContext context,
|
Pf2eDbContext context,
|
||||||
|
|||||||
+93
-36
@@ -1,105 +1,162 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
using System.Windows.Documents;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Pf2eDataScrapper.Helpers;
|
using Pf2eDataScrapper.Helpers;
|
||||||
using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers;
|
using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers;
|
||||||
using Pf2eDataScrapper.Processors;
|
using Pf2eDataScrapper.Processors;
|
||||||
|
using Pf2eDataScrapper.Processors.Attributes;
|
||||||
using Pf2eDataScrapper.Processors.Definitions;
|
using Pf2eDataScrapper.Processors.Definitions;
|
||||||
using Pf2eModel;
|
using Pf2eModel;
|
||||||
using Pf2eModel.Model;
|
using Pf2eModel.Model;
|
||||||
using Pf2eModel.Model.Base;
|
using Pf2eModel.Model.Base;
|
||||||
using Pf2eModel.Model.Base.Source;
|
|
||||||
using Pf2eModel.Model.Base.Targets;
|
using Pf2eModel.Model.Base.Targets;
|
||||||
using Pf2eModel.Model.Common.I18n;
|
using Pf2eModel.Model.Common.I18n;
|
||||||
using Pf2eModel.Model.Enum;
|
using Pf2eModel.Model.Enum;
|
||||||
using Pf2eModel.Model.Structure;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors;
|
namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Абстрактный класс-обработчик сущностей, полученных из молуля Foundry pf2e.
|
||||||
|
/// Класс предназначен для обработки данных с помощью различных обработчиков,
|
||||||
|
/// для которых указан атрибут <see cref="ProcessorAttribute"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TEntity"></typeparam>
|
||||||
|
/// <param name="databaseHelper">[DI] <inheritdoc cref="DatabaseHelper"/></param>
|
||||||
|
/// <param name="context">[DI] <inheritdoc cref="Pf2eDbContext"/></param>
|
||||||
|
/// <param name="enGlobals">[DI] <inheritdoc cref="FoundryEnGlobals"/></param>
|
||||||
|
/// <param name="input">Объект обработки вводимого JSON.</param>
|
||||||
internal abstract class FoundryEnAbstractProcessor<TEntity>(
|
internal abstract class FoundryEnAbstractProcessor<TEntity>(
|
||||||
DatabaseHelper databaseHelper,
|
DatabaseHelper databaseHelper,
|
||||||
Pf2eDbContext context,
|
Pf2eDbContext context,
|
||||||
FoundryEnGlobals enGlobals,
|
FoundryEnGlobals enGlobals,
|
||||||
ProcessorInput input
|
ProcessorInput input
|
||||||
) : AbstractInputProcessor(input)
|
) : AbstractInputProcessor(input)
|
||||||
where TEntity : class, IEntity?
|
where TEntity : class, IEntity
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc cref="DatabaseHelper"/>
|
||||||
protected DatabaseHelper Helper { get; } = databaseHelper;
|
protected DatabaseHelper Helper { get; } = databaseHelper;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Pf2eDbContext"/>
|
||||||
public Pf2eDbContext Context { get; } = context;
|
public Pf2eDbContext Context { get; } = context;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="FoundryEnGlobals"/>
|
||||||
public FoundryEnGlobals EnGlobals { get; } = enGlobals;
|
public FoundryEnGlobals EnGlobals { get; } = enGlobals;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Тип сущности.
|
||||||
|
/// </summary>
|
||||||
public abstract EntityType Type { get; }
|
public abstract EntityType Type { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Представление сущности, которое будет использоваться для обработки данных.
|
||||||
|
/// </summary>
|
||||||
public EntityView View { get; private set; } = null!;
|
public EntityView View { get; private set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Основная сущность, которая будет использоваться для обработки данных.
|
||||||
|
/// </summary>
|
||||||
public Entity Entity => View.Entity;
|
public Entity Entity => View.Entity;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Подчинённая сущность, которая будет использоваться для обработки данных.
|
||||||
|
/// </summary>
|
||||||
public TEntity Object =>
|
public TEntity Object =>
|
||||||
View.SubEntity as TEntity
|
View.SubEntity as TEntity
|
||||||
?? throw new InvalidOperationException(
|
?? throw new InvalidOperationException(
|
||||||
$"Сущность {View.SubEntity} некорректного типа, ожидался тип {typeof(TEntity)}."
|
$"Сущность {View.SubEntity} некорректного типа, ожидался тип {typeof(TEntity)}."
|
||||||
);
|
);
|
||||||
|
|
||||||
public virtual void ResolveEntity()
|
/// <summary>
|
||||||
|
/// Разрешает сущность, основываясь на входных данных.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Идентификатор сущности.</returns>
|
||||||
|
public virtual int ResolveEntity()
|
||||||
{
|
{
|
||||||
string name = Input.GetRequired<string>("name");
|
string name = GetEntityName();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int id = Context
|
List<Entity> entities = Context
|
||||||
.Entities.Include(e => e.Name)
|
.Entities.AsNoTracking()
|
||||||
|
.Include(e => e.Traits)
|
||||||
|
.ThenInclude(t => t.Entity)
|
||||||
.Where(e => Pf2eDbContext.LocaleSearch(e.Name, name) && e.Type == Type)
|
.Where(e => Pf2eDbContext.LocaleSearch(e.Name, name) && e.Type == Type)
|
||||||
.Select(e => e.Id)
|
.ToList();
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
View = new EntityView(Context, Type, id);
|
switch (entities.Count)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
throw new("сущность не найдена.");
|
||||||
|
case 1:
|
||||||
|
return entities[0].Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<string> inputTraits = Input
|
||||||
|
.GetRequired<JArray>("system.traits.value")
|
||||||
|
.Select(token => token.ToString())
|
||||||
|
.Order()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (Entity entity in entities)
|
||||||
|
{
|
||||||
|
List<string> entityTraits = entity
|
||||||
|
.Traits.Select(t => t.Entity.Name[LocaleType.English])
|
||||||
|
.Order()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (entityTraits.SequenceEqual(inputTraits))
|
||||||
|
{
|
||||||
|
return entity.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new SkipItemException(name, ex.Message);
|
throw new SkipItemException(name, ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new SkipItemException(
|
||||||
|
name,
|
||||||
|
$"Несколько сущностей \"{name}\" найдено, но ни одна не совпадает с входными данными по признакам."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public override void Process()
|
public override void Process()
|
||||||
{
|
{
|
||||||
ResolveEntity();
|
View = new(Context, Type, ResolveEntity());
|
||||||
|
|
||||||
|
AddExternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void Save()
|
||||||
|
{
|
||||||
|
Context.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получает имя сущности из входных данных.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Имя сущности.</returns>
|
||||||
|
protected virtual string GetEntityName() => Input.GetRequired<string>("name");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Генерация внешних ссылок сущности.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void AddExternal()
|
||||||
|
{
|
||||||
// External
|
// External
|
||||||
EntityExternal external = new()
|
EntityExternal external = new()
|
||||||
{
|
{
|
||||||
Entity = Entity,
|
EntityId = Entity.Id,
|
||||||
Target = EnGlobals.FoundryTarget,
|
TargetId = EnGlobals.FoundryTarget.Id,
|
||||||
ExternalId = Input.GetOptional<string>("_id"),
|
ExternalId = Input.GetOptional<string>("_id"),
|
||||||
Suffix = Input.GetRequired<string>("_id"),
|
Suffix = Input.GetRequired<string>("_id"),
|
||||||
Md5 = Input.Md5(),
|
Md5 = Input.Md5(),
|
||||||
};
|
};
|
||||||
Context.EntityExternals.Add(external);
|
Context.EntityExternals.Add(external);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Save()
|
|
||||||
{
|
|
||||||
Context.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Source GetSource(string name)
|
|
||||||
{
|
|
||||||
Source? source = Context.Sources.FirstOrDefault(s => s.Name == name);
|
|
||||||
|
|
||||||
if (source != null)
|
|
||||||
{
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
source = new() { Name = name };
|
|
||||||
|
|
||||||
Context.Sources.Add(source);
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user