Большой рефактор
This commit is contained in:
@@ -5,21 +5,17 @@ namespace Pf2eDataScrapper.Importers;
|
||||
|
||||
public class DatabaseHelper
|
||||
{
|
||||
public Pf2eDbContext Context = new();
|
||||
public readonly Pf2eDbContext Context = new();
|
||||
|
||||
public SlugHelper Slugger = new();
|
||||
public readonly SlugHelper Slugger = new();
|
||||
|
||||
private int _id = 0;
|
||||
private int _id;
|
||||
|
||||
public int NextEntityId
|
||||
{
|
||||
get => ++_id;
|
||||
set => _id = value;
|
||||
}
|
||||
public int NextEntityId => ++_id;
|
||||
|
||||
private DatabaseHelper()
|
||||
{
|
||||
NextEntityId = Context.Entities.Any() ? Context.Entities.Max(e => e.Id) : 0;
|
||||
_id = Context.Entities.Any() ? Context.Entities.Max(e => e.Id) : 0;
|
||||
}
|
||||
|
||||
public string GenerateSlug(string name)
|
||||
|
||||
@@ -40,7 +40,7 @@ internal class AonprdLoader(AonprdImporter importer)
|
||||
|
||||
public IEnumerable<LoaderEntry> Entries(string[] types)
|
||||
{
|
||||
foreach (string? file in Compendium.Files(types))
|
||||
foreach (string file in Compendium.Files(types))
|
||||
{
|
||||
using StreamReader fileReader = new(Path.Combine(Importer.Dir, $"{file}.json"));
|
||||
JArray array = JArray.Parse(fileReader.ReadToEnd());
|
||||
|
||||
+57
-42
@@ -1,13 +1,13 @@
|
||||
using Konsole;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium;
|
||||
using Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
|
||||
using static Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.AbstractProcessor;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder;
|
||||
|
||||
internal class AonprdDataBuilder(AonprdLoader loader)
|
||||
{
|
||||
public Pf2eDatabase Database = Pf2eDatabase.Instance;
|
||||
public readonly Pf2eDatabase Database = Pf2eDatabase.Instance;
|
||||
|
||||
/// <summary>
|
||||
/// Загрузчик данных.
|
||||
@@ -19,7 +19,7 @@ internal class AonprdDataBuilder(AonprdLoader loader)
|
||||
/// </summary>
|
||||
public AonprdCompendium Compendium => Loader.Compendium;
|
||||
|
||||
public AonprdProcessorCollection Processors = new();
|
||||
public readonly AonprdProcessorCollection Processors = new();
|
||||
|
||||
public void TruncateTables()
|
||||
{
|
||||
@@ -30,64 +30,79 @@ internal class AonprdDataBuilder(AonprdLoader loader)
|
||||
Console.WriteLine("Truncation completed!");
|
||||
}
|
||||
|
||||
public void Build()
|
||||
protected ConcurrentWriter Window = null!;
|
||||
|
||||
protected Window Output = null!;
|
||||
|
||||
protected ProgressBar ProcessProgressBar = null!;
|
||||
|
||||
protected ProgressBar SubProcessProgressBar = null!;
|
||||
|
||||
protected void ConfigureWindow()
|
||||
{
|
||||
Console.WriteLine("Building data...");
|
||||
Window = new Window(0, 0, Console.WindowWidth, Console.WindowHeight).Concurrent();
|
||||
|
||||
ConcurrentWriter window = new Window(
|
||||
0,
|
||||
0,
|
||||
Console.WindowWidth,
|
||||
Console.WindowHeight
|
||||
).Concurrent();
|
||||
|
||||
IConsole bars = window.OpenBox(
|
||||
IConsole bars = Window.OpenBox(
|
||||
"Progress",
|
||||
Console.WindowWidth,
|
||||
4,
|
||||
new BoxStyle { Body = Colors.WhiteOnBlack }
|
||||
new() { Body = Colors.WhiteOnBlack }
|
||||
);
|
||||
|
||||
Window output = new(0, 4, Console.WindowWidth, Console.WindowHeight - 4, window);
|
||||
Output = new(0, 4, Console.WindowWidth, Console.WindowHeight - 4, Window);
|
||||
|
||||
ProgressBar bar1 = new(bars, Processors.Items.Count, 15);
|
||||
ProgressBar bar2 = new(bars, 1, 15);
|
||||
int i = 0;
|
||||
ProcessProgressBar = new(bars, Processors.Items.Count, 15);
|
||||
|
||||
SubProcessProgressBar = new(bars, 1, 15);
|
||||
}
|
||||
|
||||
protected void RunProcessor(AonprdProcessorCollection.ProcessorItem item, JObject json)
|
||||
{
|
||||
AonprdProcessorInput input = new(json);
|
||||
AbstractProcessor processor = (AbstractProcessor)item.Constructor.Invoke([input]);
|
||||
|
||||
try
|
||||
{
|
||||
processor.Process();
|
||||
processor.Save();
|
||||
}
|
||||
catch (LegacyItemException ex)
|
||||
{
|
||||
Output.WriteLine(ex.Message);
|
||||
}
|
||||
catch (SkipItemException ex)
|
||||
{
|
||||
Output.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public void Build()
|
||||
{
|
||||
ConfigureWindow();
|
||||
|
||||
foreach (AonprdProcessorCollection.ProcessorItem item in Processors.Iterate())
|
||||
{
|
||||
bar1.Refresh(i++, $"{item.Attribute.Name}");
|
||||
ProcessProgressBar.Next(item.Attribute.Name);
|
||||
|
||||
bar2.Max = Compendium.Count([item.Attribute.Type]);
|
||||
int j = 0;
|
||||
if (item.Attribute.Type is null)
|
||||
{
|
||||
RunProcessor(item, []);
|
||||
continue;
|
||||
}
|
||||
|
||||
SubProcessProgressBar.Max = Compendium.Count([item.Attribute.Type]);
|
||||
|
||||
foreach (AonprdLoader.LoaderEntry entry in Loader.Entries(item.Attribute.Type))
|
||||
{
|
||||
bar2.Refresh(j++, $"{entry.Id}");
|
||||
|
||||
AonprdProcessorInput input = new(entry.Json);
|
||||
AbstractProcessor processor = (AbstractProcessor)item.Constructor.Invoke([input]);
|
||||
|
||||
try
|
||||
{
|
||||
processor.Process();
|
||||
processor.Save();
|
||||
}
|
||||
catch (LegacyItemException ex)
|
||||
{
|
||||
output.WriteLine(ex.Message);
|
||||
}
|
||||
catch (SkipItemException ex)
|
||||
{
|
||||
output.WriteLine(ex.Message);
|
||||
}
|
||||
SubProcessProgressBar.Next($"{entry.Id}");
|
||||
RunProcessor(item, entry.Json);
|
||||
}
|
||||
|
||||
bar2.Refresh(j, "Processor completed");
|
||||
SubProcessProgressBar.Next("Ready");
|
||||
}
|
||||
|
||||
bar1.Refresh(i, "Done!");
|
||||
ProcessProgressBar.Next("Done!");
|
||||
|
||||
window.Clear();
|
||||
Window.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class AonprdProcessorAttribute(string name, string type, string[] dependencies) : Attribute
|
||||
public class AonprdProcessorAttribute(string name, string? type, string[] dependencies) : Attribute
|
||||
{
|
||||
public readonly string Name = name;
|
||||
|
||||
public readonly string Type = type;
|
||||
public readonly string? Type = type;
|
||||
|
||||
public readonly IEnumerable<string> Dependencies = dependencies;
|
||||
|
||||
+5
-4
@@ -1,6 +1,7 @@
|
||||
using System.Reflection;
|
||||
using Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder;
|
||||
|
||||
internal class AonprdProcessorCollection
|
||||
{
|
||||
@@ -41,13 +42,13 @@ internal class AonprdProcessorCollection
|
||||
);
|
||||
if (collision is not null)
|
||||
{
|
||||
throw new Exception(
|
||||
throw new(
|
||||
$"Multiply attributes 'AonprdProcessor' have same name '{attribute.Name}'."
|
||||
+ $" They are added to classes: '{type.FullName}' and '{collision.Constructor.DeclaringType!.FullName}'"
|
||||
);
|
||||
}
|
||||
|
||||
Items.Add(new ProcessorItem(attribute, constructor));
|
||||
Items.Add(new(attribute, constructor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +66,7 @@ internal class AonprdProcessorCollection
|
||||
}
|
||||
|
||||
IEnumerable<int> dependencyPriorities = item.Attribute.Dependencies.Select(d =>
|
||||
priorities.TryGetValue(d, out int value) ? value : -1
|
||||
priorities.GetValueOrDefault(d, -1)
|
||||
);
|
||||
|
||||
if (dependencyPriorities.Any(p => p == -1))
|
||||
+6
-5
@@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Helpers;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder;
|
||||
|
||||
@@ -84,10 +85,10 @@ internal class AonprdProcessorInput(JObject input) : ProcessorInput(input)
|
||||
|
||||
public class ActionStruct
|
||||
{
|
||||
public int Actions = 0;
|
||||
public int MaxActions = 0;
|
||||
public bool IsPassive = false;
|
||||
public bool IsReaction = false;
|
||||
public bool IsFreeAction = false;
|
||||
public int Actions;
|
||||
public int MaxActions;
|
||||
public bool IsPassive;
|
||||
public bool IsReaction;
|
||||
public bool IsFreeAction;
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using Pf2eModel.Model.Base.Targets;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Helpers;
|
||||
|
||||
internal class AonprdBuilderGlobals
|
||||
{
|
||||
public ExternalTarget AonprdTarget = null!;
|
||||
|
||||
private AonprdBuilderGlobals() { }
|
||||
|
||||
public static AonprdBuilderGlobals Instance = new AonprdBuilderGlobals();
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using Pf2eModel.Model.Enum;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder;
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Helpers;
|
||||
|
||||
public static class AonprdEnumResolver
|
||||
{
|
||||
+8
-7
@@ -1,16 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Helpers;
|
||||
|
||||
internal partial class StringHelper
|
||||
{
|
||||
private StringHelper() { }
|
||||
|
||||
public string ResolveSource(string input)
|
||||
{
|
||||
Match match = SourceSuffixRegex().Match(input);
|
||||
return match.Captures.Count > 0 ? match.Captures[0].Value : "";
|
||||
}
|
||||
|
||||
public static StringHelper Instance { get; } = new();
|
||||
|
||||
[GeneratedRegex(@"^\[.*?\]\(.*?\)\s+(.*)$")]
|
||||
+224
@@ -0,0 +1,224 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Pf2eModel;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel.Model.Base;
|
||||
using Pf2eModel.Model.Base.Source;
|
||||
using Pf2eModel.Model.Base.Targets;
|
||||
using Pf2eModel.Model.Common.I18n;
|
||||
using Pf2eModel.Model.Enum;
|
||||
using Pf2eModel.Model.Structure;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
|
||||
|
||||
internal abstract class AbstractEntityProcessor(AonprdProcessorInput input)
|
||||
: AbstractProcessor(input)
|
||||
{
|
||||
public Entity Entity { get; } = new();
|
||||
|
||||
public abstract EntityType Type { get; }
|
||||
|
||||
public abstract IEntity Object { get; }
|
||||
|
||||
public abstract void Add();
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
if (Input.GetOptional<JArray>("remaster_id") is not null)
|
||||
{
|
||||
string id = Input.GetRequired<string>("id");
|
||||
string name = Input.GetRequired<string>("name");
|
||||
|
||||
ProcessLegacy(id, name);
|
||||
throw new LegacyItemException(name);
|
||||
}
|
||||
|
||||
AddEntity();
|
||||
AddAlias();
|
||||
AddSource();
|
||||
AddExternal();
|
||||
AddTraits();
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
Add();
|
||||
Context.SaveChanges();
|
||||
}
|
||||
|
||||
protected string AddedDescription(string path) =>
|
||||
$"\r\n\r\n========== [{path}] ==========\r\n\r\n{Input.GetOptional<string>(path) ?? ""}";
|
||||
|
||||
protected string AddedDescription(string[] paths) =>
|
||||
string.Join("", paths.Select(AddedDescription));
|
||||
|
||||
protected virtual string GetDescription() => Input.GetRequired<string>("markdown");
|
||||
|
||||
protected virtual void AddEntity()
|
||||
{
|
||||
Entity.Id = Helper.NextEntityId;
|
||||
Entity.Type = Type;
|
||||
Entity.Name[LocaleType.English] = Input.GetRequired<string>("name");
|
||||
Entity.Img = "";
|
||||
Entity.Description = GetDescription();
|
||||
Entity.Rarity = Input.EnumOptional("rarity", EntityRarity.Common);
|
||||
Entity.Slug = Helper.GenerateSlug(Entity.Name[LocaleType.English]);
|
||||
Entity.IsTranslated = false;
|
||||
Entity.IsChecked = false;
|
||||
|
||||
Object.Entity = Entity;
|
||||
Object.Id = Entity.Id;
|
||||
|
||||
Context.Entities.Add(Entity);
|
||||
}
|
||||
|
||||
protected virtual void AddAlias()
|
||||
{
|
||||
JArray? legacyIdArray = Input.GetOptional<JArray>("legacy_id");
|
||||
|
||||
if (legacyIdArray is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string legacyId = legacyIdArray[0].ToString();
|
||||
|
||||
if (LegacyAliases.TryGetValue(legacyId, out string? legacyName))
|
||||
{
|
||||
// if (legacyName != Entity.Name[LocaleType.English])
|
||||
Entity.Name[LocaleType.LegacyEnglish] = legacyName;
|
||||
|
||||
LegacyAliases.Remove(legacyId);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemasterWithoutLegacy.Add(legacyId, Entity);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void AddSource()
|
||||
{
|
||||
string name = Input.GetRequired<string>("source[0]");
|
||||
|
||||
Source? source = Context.Sources.FirstOrDefault(s => s.Name == name);
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
source = new()
|
||||
{
|
||||
Name = name,
|
||||
Category = Input.EnumRequired<SourceCategory>("primary_source_category"),
|
||||
ReleaseDate = DateOnly.Parse(Input.GetRequired<string>("release_date")),
|
||||
};
|
||||
|
||||
Context.Sources.Add(source);
|
||||
}
|
||||
|
||||
EntitySource entitySource = new()
|
||||
{
|
||||
Entity = Entity,
|
||||
Source = source,
|
||||
Suffix = StringHelper.ResolveSource(Input.GetRequired<string>("source_markdown")),
|
||||
IsRemaster = Input.GetOptional<JArray>("legacy_id") is not null,
|
||||
};
|
||||
|
||||
Context.EntitySources.Add(entitySource);
|
||||
}
|
||||
|
||||
protected virtual void AddExternal()
|
||||
{
|
||||
EntityExternal external = new()
|
||||
{
|
||||
Entity = Entity,
|
||||
Target = Globals.AonprdTarget,
|
||||
Suffix = Input.GetRequired<string>("url"),
|
||||
Md5 = Md5(Input.Input.ToString()),
|
||||
};
|
||||
|
||||
Context.EntityExternals.Add(external);
|
||||
}
|
||||
|
||||
protected virtual void AddTraits()
|
||||
{
|
||||
JToken? traitsJson = Input.Input.SelectToken("trait");
|
||||
|
||||
if (traitsJson?.Type != JTokenType.Array)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IEnumerable<string> names = traitsJson.ToArray().Select(jToken => jToken.ToString());
|
||||
List<Entity> traitEntities = Context
|
||||
.Traits.Select(t => t.Entity)
|
||||
// ReSharper disable once EntityFramework.UnsupportedServerSideFunctionCall
|
||||
.Where(e => Pf2eDbContext.LocaleSearchArray(e.Name, names))
|
||||
.ToList();
|
||||
|
||||
List<Trait> traits = Context
|
||||
.Traits.Include(t => t.Entity)
|
||||
.ThenInclude(entity => entity.Name)
|
||||
.Where(t => traitEntities.Contains(t.Entity))
|
||||
.ToList();
|
||||
|
||||
foreach (string name in names)
|
||||
{
|
||||
if (!traits.Any(t => t.Entity.Name.Contains(name)))
|
||||
{
|
||||
throw new Exception($"Trait '{name}' is not found!!!");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Trait trait in traits)
|
||||
{
|
||||
Entity.Traits.Add(trait);
|
||||
}
|
||||
}
|
||||
|
||||
protected void ProcessLegacy(string id, string name)
|
||||
{
|
||||
if (RemasterWithoutLegacy.TryGetValue(id, out Entity? remastered))
|
||||
{
|
||||
// if (remastered.ToString() != name)
|
||||
remastered.Name[LocaleType.LegacyEnglish] = name;
|
||||
|
||||
RemasterWithoutLegacy.Remove(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
LegacyAliases.Add(id, name);
|
||||
}
|
||||
}
|
||||
|
||||
public string GenerateExtra(params string[] args)
|
||||
{
|
||||
Dictionary<string, object?> data = [];
|
||||
|
||||
foreach (string key in args)
|
||||
{
|
||||
data.Add(key, Input.Input.SelectToken(key));
|
||||
}
|
||||
|
||||
return JsonConvert.SerializeObject(data, new JsonSerializerSettings());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
protected static readonly Dictionary<string, string> LegacyAliases = [];
|
||||
|
||||
protected static readonly Dictionary<string, Entity> RemasterWithoutLegacy = [];
|
||||
}
|
||||
|
||||
public class LegacyItemException(string name)
|
||||
: Exception($"Item '{name}' is linked with newer version, skipping.") { }
|
||||
|
||||
public class SkipItemException(string name, string reason)
|
||||
: Exception($"Item '{name}' is skipped, reason: {reason}.") { }
|
||||
+8
-237
@@ -1,250 +1,21 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Helpers;
|
||||
using Pf2eModel;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel.Model.Base;
|
||||
using Pf2eModel.Model.Base.Source;
|
||||
using Pf2eModel.Model.Base.Targets;
|
||||
using Pf2eModel.Model.Common.I18n;
|
||||
using Pf2eModel.Model.Enum;
|
||||
using Pf2eModel.Model.Structure;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
|
||||
|
||||
internal abstract partial class AbstractProcessor(AonprdProcessorInput input)
|
||||
internal abstract class AbstractProcessor(AonprdProcessorInput input)
|
||||
{
|
||||
protected DatabaseHelper Helper = DatabaseHelper.Instance;
|
||||
protected readonly DatabaseHelper Helper = DatabaseHelper.Instance;
|
||||
|
||||
protected StringHelper StringHelper = StringHelper.Instance;
|
||||
protected readonly StringHelper StringHelper = StringHelper.Instance;
|
||||
|
||||
protected readonly AonprdBuilderGlobals Globals = AonprdBuilderGlobals.Instance;
|
||||
|
||||
public readonly Pf2eDbContext Context = DatabaseHelper.DbContext;
|
||||
|
||||
public readonly AonprdProcessorInput Input = input;
|
||||
|
||||
public Entity Entity { get; set; } = new();
|
||||
public abstract void Process();
|
||||
|
||||
public abstract EntityType Type { get; }
|
||||
|
||||
public abstract IEntity Object { get; }
|
||||
|
||||
protected abstract void Add();
|
||||
|
||||
public virtual void Process()
|
||||
{
|
||||
if (Input.GetOptional<JArray>("remaster_id") is not null)
|
||||
{
|
||||
string id = Input.GetRequired<string>("id");
|
||||
string name = Input.GetRequired<string>("name");
|
||||
|
||||
ProcessLegacy(id, name);
|
||||
throw new LegacyItemException(name);
|
||||
}
|
||||
|
||||
AddEntity();
|
||||
AddAlias();
|
||||
AddSource();
|
||||
AddExternal();
|
||||
AddTraits();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
Add();
|
||||
Context.SaveChanges();
|
||||
}
|
||||
|
||||
protected string AddedDescription(string path) =>
|
||||
$"\r\n\r\n========== [{path}] ==========\r\n\r\n{Input.GetOptional<string>(path) ?? ""}";
|
||||
|
||||
protected string AddedDescription(string[] paths) =>
|
||||
string.Join("", paths.Select(AddedDescription));
|
||||
|
||||
protected virtual string GetDescription() => Input.GetRequired<string>("markdown");
|
||||
|
||||
protected virtual void AddEntity()
|
||||
{
|
||||
Entity.Id = Helper.NextEntityId;
|
||||
Entity.Type = Type;
|
||||
Entity.Name[LocaleType.English] = Input.GetRequired<string>("name");
|
||||
Entity.Img = "";
|
||||
Entity.Description = GetDescription();
|
||||
Entity.Rarity = Input.EnumOptional<EntityRarity>("rarity", EntityRarity.Common);
|
||||
Entity.Slug = Helper.GenerateSlug(Entity.Name[LocaleType.English]);
|
||||
Entity.IsTranslated = false;
|
||||
Entity.IsChecked = false;
|
||||
|
||||
Object.Entity = Entity;
|
||||
Object.Id = Entity.Id;
|
||||
|
||||
Context.Entities.Add(Entity);
|
||||
}
|
||||
|
||||
protected virtual void AddAlias()
|
||||
{
|
||||
JArray? legacyIdArray = Input.GetOptional<JArray>("legacy_id");
|
||||
|
||||
if (legacyIdArray is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string legacyId = legacyIdArray[0].ToString();
|
||||
|
||||
if (LegacyAliases.TryGetValue(legacyId, out string? legacyName))
|
||||
{
|
||||
// if (legacyName != Entity.Name[LocaleType.English])
|
||||
Entity.Name[LocaleType.LegacyEnglish] = legacyName;
|
||||
|
||||
LegacyAliases.Remove(legacyId);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemasterWithoutLegacy.Add(legacyId, Entity);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void AddSource()
|
||||
{
|
||||
string name = Input.GetRequired<string>("source[0]");
|
||||
|
||||
Source? source = Context.Sources.FirstOrDefault(s => s.Name == name);
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
source = new()
|
||||
{
|
||||
Name = name,
|
||||
Category = Input.EnumRequired<SourceCategory>("primary_source_category"),
|
||||
ReleaseDate = DateOnly.Parse(Input.GetRequired<string>("release_date")),
|
||||
};
|
||||
|
||||
Context.Sources.Add(source);
|
||||
}
|
||||
string sourceMarkdown = Input.GetRequired<string>("source_markdown");
|
||||
Match match = SourceSuffixRegex().Match(sourceMarkdown);
|
||||
|
||||
EntitySource entitySource = new()
|
||||
{
|
||||
Entity = Entity,
|
||||
Source = source,
|
||||
Suffix = ((match?.Captures.Count > 0) ? match?.Captures[0]?.Value : "") ?? "",
|
||||
IsRemaster = Input.GetOptional<JArray>("legacy_id") is not null,
|
||||
};
|
||||
|
||||
Context.EntitySources.Add(entitySource);
|
||||
}
|
||||
|
||||
protected virtual void AddExternal()
|
||||
{
|
||||
if (AonprdTarget is null)
|
||||
{
|
||||
AonprdTarget = Context.ExternalTargets.FirstOrDefault(t =>
|
||||
t.Name == AonprdImporter.SourceName
|
||||
);
|
||||
|
||||
AonprdTarget ??= new()
|
||||
{
|
||||
Name = AonprdImporter.SourceName,
|
||||
Icon = "http://www.google.com/s2/favicons?domain=2e.aonprd.com",
|
||||
Prefix = "https://2e.aonprd.com",
|
||||
};
|
||||
}
|
||||
|
||||
EntityExternal external = new()
|
||||
{
|
||||
Entity = Entity,
|
||||
Target = AonprdTarget,
|
||||
Suffix = Input.GetRequired<string>("url"),
|
||||
Md5 = Md5(Input.Input.ToString()),
|
||||
};
|
||||
Context.EntityExternals.Add(external);
|
||||
}
|
||||
|
||||
protected virtual void AddTraits()
|
||||
{
|
||||
JToken? traitsJson = Input.Input.SelectToken("trait");
|
||||
|
||||
if (traitsJson?.Type != JTokenType.Array)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IEnumerable<string> names = traitsJson.ToArray().Select(jToken => jToken.ToString());
|
||||
List<Entity> traitEntities = Context
|
||||
.Traits.Select(t => t.Entity)
|
||||
.Where(e => Pf2eDbContext.LocaleSearchArray(e.Name, names))
|
||||
.ToList();
|
||||
|
||||
List<Trait> traits = Context
|
||||
.Traits.Include(t => t.Entity)
|
||||
.Where(t => traitEntities.Contains(t.Entity))
|
||||
.ToList();
|
||||
|
||||
foreach (string name in names)
|
||||
{
|
||||
if (!traits.Any(t => t.Entity.Name.Contains(name)))
|
||||
{
|
||||
throw new Exception($"Trait '{name}' is not found!!!");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Trait trait in traits)
|
||||
{
|
||||
Entity.Traits.Add(trait);
|
||||
}
|
||||
}
|
||||
|
||||
protected void ProcessLegacy(string id, string name)
|
||||
{
|
||||
if (RemasterWithoutLegacy.TryGetValue(id, out Entity? remastered))
|
||||
{
|
||||
// if (remastered.ToString() != name)
|
||||
remastered.Name[LocaleType.LegacyEnglish] = name;
|
||||
|
||||
RemasterWithoutLegacy.Remove(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
LegacyAliases.Add(id, name);
|
||||
}
|
||||
}
|
||||
|
||||
public string GenerateExtra(params string[] args)
|
||||
{
|
||||
Dictionary<string, object?> data = [];
|
||||
|
||||
foreach (string key in args)
|
||||
{
|
||||
data.Add(key, Input.Input.SelectToken(key));
|
||||
}
|
||||
|
||||
return JsonConvert.SerializeObject(data, new JsonSerializerSettings() { });
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
protected static ExternalTarget? AonprdTarget = null;
|
||||
|
||||
protected static Dictionary<string, string> LegacyAliases = [];
|
||||
|
||||
protected static Dictionary<string, Entity> RemasterWithoutLegacy = [];
|
||||
|
||||
[GeneratedRegex(@"^\[.*?\]\(.*?\)\s+(.*)$")]
|
||||
private static partial Regex SourceSuffixRegex();
|
||||
|
||||
public class LegacyItemException(string name)
|
||||
: Exception($"Item '{name}' is linked with newer version, skipping.") { }
|
||||
|
||||
public class SkipItemException(string name, string reason)
|
||||
: Exception($"Item '{name}' is skipped, reason: {reason}.") { }
|
||||
public abstract void Save();
|
||||
}
|
||||
|
||||
+31
-48
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Pf2eModel;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel;
|
||||
using Pf2eModel.Model.Base;
|
||||
using Pf2eModel.Model.Common.I18n;
|
||||
using Pf2eModel.Model.Enum;
|
||||
@@ -13,7 +7,7 @@ using Pf2eModel.Model.Structure;
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
|
||||
|
||||
internal abstract class AbstractSubclassProcessor(AonprdProcessorInput input)
|
||||
: AbstractProcessor(input)
|
||||
: AbstractEntityProcessor(input)
|
||||
{
|
||||
public override EntityType Type => EntityType.Subclass;
|
||||
|
||||
@@ -23,7 +17,7 @@ internal abstract class AbstractSubclassProcessor(AonprdProcessorInput input)
|
||||
|
||||
public abstract string GroupName { get; }
|
||||
|
||||
protected override void Add() => Context.Subclasses.Add(Object);
|
||||
public override void Add() => Context.Subclasses.Add(Object);
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
@@ -37,51 +31,40 @@ internal abstract class AbstractSubclassProcessor(AonprdProcessorInput input)
|
||||
public SubclassGroup GetGroup()
|
||||
{
|
||||
SubclassGroup? group = Context.SubclassGroups.FirstOrDefault(g =>
|
||||
// ReSharper disable once EntityFramework.UnsupportedServerSideFunctionCall
|
||||
Pf2eDbContext.LocaleSearch(g.Entity.Name, GroupName)
|
||||
);
|
||||
|
||||
if (group is null)
|
||||
if (group is not null)
|
||||
{
|
||||
Class? cl =
|
||||
(ClassName is not null)
|
||||
? Context.Classes.FirstOrDefault(c =>
|
||||
Pf2eDbContext.LocaleSearch(c.Entity.Name, GroupName)
|
||||
)
|
||||
: null;
|
||||
|
||||
Entity groupEntity = new()
|
||||
{
|
||||
Id = Helper.NextEntityId,
|
||||
Type = EntityType.SubclassGroup,
|
||||
Img = "",
|
||||
Description = "",
|
||||
Rarity = EntityRarity.Common,
|
||||
IsTranslated = false,
|
||||
IsChecked = false,
|
||||
};
|
||||
|
||||
groupEntity.Name[LocaleType.English] = GroupName;
|
||||
groupEntity.Slug = Helper.GenerateSlug(GroupName);
|
||||
Context.Entities.Add(groupEntity);
|
||||
|
||||
/*
|
||||
|
||||
Entity.Id = Helper.NextEntityId;
|
||||
Entity.Type = Type;
|
||||
Entity.Name[LocaleType.English] = Input.GetRequired<string>("name");
|
||||
Entity.Img = "";
|
||||
Entity.Description = GetDescription();
|
||||
Entity.Rarity = Input.EnumOptional<EntityRarity>("rarity", EntityRarity.Common);
|
||||
Entity.Slug = Helper.GenerateSlug(Entity.Name[LocaleType.English]);
|
||||
Entity.IsTranslated = false;
|
||||
Entity.IsChecked = false;
|
||||
|
||||
*/
|
||||
|
||||
group = new SubclassGroup() { Entity = groupEntity, Class = cl };
|
||||
Context.SubclassGroups.Add(group);
|
||||
return group;
|
||||
}
|
||||
|
||||
Class? cl = ClassName is not null
|
||||
? Context.Classes.FirstOrDefault(c =>
|
||||
// ReSharper disable once EntityFramework.UnsupportedServerSideFunctionCall
|
||||
Pf2eDbContext.LocaleSearch(c.Entity.Name, GroupName)
|
||||
)
|
||||
: null;
|
||||
|
||||
Entity groupEntity = new()
|
||||
{
|
||||
Id = Helper.NextEntityId,
|
||||
Type = EntityType.SubclassGroup,
|
||||
Img = "",
|
||||
Description = "",
|
||||
Rarity = EntityRarity.Common,
|
||||
IsTranslated = false,
|
||||
IsChecked = false,
|
||||
Name = { [LocaleType.English] = GroupName },
|
||||
Slug = Helper.GenerateSlug(GroupName),
|
||||
};
|
||||
|
||||
Context.Entities.Add(groupEntity);
|
||||
|
||||
group = new() { Entity = groupEntity, Class = cl };
|
||||
Context.SubclassGroups.Add(group);
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
using Pf2eModel.Model.Base.Targets;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Common;
|
||||
|
||||
[AonprdProcessor("external", null, [])]
|
||||
internal class ExternalProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
|
||||
{
|
||||
public ExternalTarget AonprdTarget = null!;
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
AonprdTarget = new()
|
||||
{
|
||||
Name = AonprdImporter.SourceName,
|
||||
Icon = "http://www.google.com/s2/favicons?domain=2e.aonprd.com",
|
||||
Prefix = "https://2e.aonprd.com",
|
||||
};
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
Context.ExternalTargets.Add(AonprdTarget);
|
||||
|
||||
Globals.AonprdTarget = AonprdTarget;
|
||||
}
|
||||
}
|
||||
+9
-13
@@ -1,29 +1,25 @@
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel.Model.Base.Source;
|
||||
using Pf2eModel.Model.Base.Source;
|
||||
using Pf2eModel.Model.Enum;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Types;
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Common;
|
||||
|
||||
[AonprdProcessor("source", new string[] { })]
|
||||
[AonprdProcessor("source", [])]
|
||||
internal class SourceProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
|
||||
{
|
||||
public override EntityType Type => EntityType.Unknown;
|
||||
|
||||
public override IEntity? Object => null;
|
||||
|
||||
protected override void Add() { }
|
||||
protected Source Source = null!;
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
// base.Process();
|
||||
|
||||
Source source = new()
|
||||
Source = new()
|
||||
{
|
||||
Name = Input.GetRequired<string>("name"),
|
||||
Category = Input.EnumRequired<SourceCategory>("primary_source_category"),
|
||||
ReleaseDate = DateOnly.Parse(Input.GetRequired<string>("release_date")),
|
||||
};
|
||||
}
|
||||
|
||||
Context.Sources.Add(source);
|
||||
public override void Save()
|
||||
{
|
||||
Context.Sources.Add(Source);
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using Pf2eModel.Model.Common;
|
||||
using Pf2eModel.Model.Enum;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Common;
|
||||
|
||||
[AonprdProcessor("skill", [])]
|
||||
internal class TrainingProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
|
||||
{
|
||||
public Training Training = null!;
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
Training = new() { Name = Input.GetRequired<string>("name"), Type = TrainingType.Skill };
|
||||
}
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
Context.Trainings.Add(Training);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -7,7 +7,7 @@ internal class ApparitionProcessor(AonprdProcessorInput input) : AbstractSubclas
|
||||
{
|
||||
public override Subclass Object { get; } = new();
|
||||
|
||||
public override string? ClassName => "Animist";
|
||||
public override string ClassName => "Animist";
|
||||
|
||||
public override string GroupName => "Apparition";
|
||||
|
||||
|
||||
+3
-3
@@ -3,13 +3,13 @@
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Types;
|
||||
|
||||
[AonprdProcessor("action")]
|
||||
internal class ActionProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
|
||||
internal class ActionProcessor(AonprdProcessorInput input) : AbstractEntityProcessor(input)
|
||||
{
|
||||
public override EntityType Type => EntityType.Action;
|
||||
|
||||
public override Pf2eModel.Model.Structure.Action Object { get; } = new();
|
||||
|
||||
protected override void Add() => Context.Actions.Add(Object);
|
||||
public override void Add() => Context.Actions.Add(Object);
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
@@ -24,7 +24,7 @@ internal class ActionProcessor(AonprdProcessorInput input) : AbstractProcessor(i
|
||||
Object.IsFreeAction = action.IsFreeAction;
|
||||
Object.IsPassive = action.IsPassive;
|
||||
Object.IsReaction = action.IsReaction;
|
||||
;
|
||||
|
||||
Object.Extra = GenerateExtra("school");
|
||||
}
|
||||
|
||||
|
||||
+12
-14
@@ -1,19 +1,17 @@
|
||||
using LinqToDB;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Pf2eModel.Model.Enum;
|
||||
using Pf2eModel.Model.Structure;
|
||||
using Pf2eModel.Model.Structure.AncestryRelation;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Types;
|
||||
|
||||
[AonprdProcessor("ancestry", ["trait", "language"])]
|
||||
internal class AncestryProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
|
||||
internal class AncestryProcessor(AonprdProcessorInput input) : AbstractEntityProcessor(input)
|
||||
{
|
||||
public override EntityType Type => EntityType.Ancestry;
|
||||
|
||||
public override Ancestry Object { get; } = new();
|
||||
|
||||
protected override void Add() => Context.Ancestries.Add(Object);
|
||||
public override void Add() => Context.Ancestries.Add(Object);
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
@@ -36,7 +34,7 @@ internal class AncestryProcessor(AonprdProcessorInput input) : AbstractProcessor
|
||||
|
||||
Object.Speed = Convert.ToInt32(Input.GetOptional<int>("speed.land"));
|
||||
|
||||
Object.Vision = Input.EnumOptional<AncestryVision>("vision", AncestryVision.Normal);
|
||||
Object.Vision = Input.EnumOptional("vision", AncestryVision.Normal);
|
||||
|
||||
AddBoosts("attribute", true);
|
||||
AddBoosts("attribute_flaw", false);
|
||||
@@ -59,14 +57,14 @@ internal class AncestryProcessor(AonprdProcessorInput input) : AbstractProcessor
|
||||
|
||||
foreach (string boost in boosts)
|
||||
{
|
||||
AncestryBoost ancestryBoost = new()
|
||||
{
|
||||
Ancestry = Object,
|
||||
Boost = isBoost,
|
||||
Value = Input.Enum<AttributeValues>(boost),
|
||||
};
|
||||
|
||||
Context.AncestryBoosts.Add(ancestryBoost);
|
||||
Context.AncestryBoosts.Add(
|
||||
new()
|
||||
{
|
||||
Ancestry = Object,
|
||||
Boost = isBoost,
|
||||
Value = Input.Enum<AttributeValues>(boost),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -4,13 +4,13 @@ using Pf2eModel.Model.Structure;
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Types;
|
||||
|
||||
[AonprdProcessor("archetype")]
|
||||
internal class ArchetypeProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
|
||||
internal class ArchetypeProcessor(AonprdProcessorInput input) : AbstractEntityProcessor(input)
|
||||
{
|
||||
public override EntityType Type => EntityType.Archetype;
|
||||
|
||||
public override Archetype Object { get; } = new();
|
||||
|
||||
protected override void Add() => Context.Archetypes.Add(Object);
|
||||
public override void Add() => Context.Archetypes.Add(Object);
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
|
||||
+2
-2
@@ -6,13 +6,13 @@ using Pf2eModel.Model.Structure.BackgroundRelation;
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Types;
|
||||
|
||||
[AonprdProcessor("background")]
|
||||
internal class BackgroundProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
|
||||
internal class BackgroundProcessor(AonprdProcessorInput input) : AbstractEntityProcessor(input)
|
||||
{
|
||||
public override EntityType Type => EntityType.Background;
|
||||
|
||||
public override Background Object { get; } = new();
|
||||
|
||||
protected override void Add() => Context.Backgrounds.Add(Object);
|
||||
public override void Add() => Context.Backgrounds.Add(Object);
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
|
||||
+2
-5
@@ -1,6 +1,4 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using LinqToDB;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Pf2eModel.Model.Common;
|
||||
using Pf2eModel.Model.Enum;
|
||||
@@ -10,13 +8,13 @@ using Pf2eModel.Model.Structure.ClassRelation;
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Types;
|
||||
|
||||
[AonprdProcessor("class", ["trait", "source", "skill"])]
|
||||
internal class ClassProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
|
||||
internal class ClassProcessor(AonprdProcessorInput input) : AbstractEntityProcessor(input)
|
||||
{
|
||||
public override EntityType Type => EntityType.Class;
|
||||
|
||||
public override Class Object { get; } = new();
|
||||
|
||||
protected override void Add() => Context.Classes.Add(Object);
|
||||
public override void Add() => Context.Classes.Add(Object);
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
@@ -156,7 +154,6 @@ internal class ClassProcessor(AonprdProcessorInput input) : AbstractProcessor(in
|
||||
.Where(s => s != "")
|
||||
.Select(s => string.Concat(s[0].ToString().ToUpper(), s.AsSpan(1)))
|
||||
.ToArray();
|
||||
;
|
||||
}
|
||||
|
||||
protected ICollection<ClassTraining> GetSaveTrainings()
|
||||
|
||||
+4
-3
@@ -6,13 +6,13 @@ using Pf2eModel.Model.Structure;
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Types;
|
||||
|
||||
// [AonprdProcessor("feat", ["trait", "source", "archetype"])]
|
||||
internal class FeatProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
|
||||
internal class FeatProcessor(AonprdProcessorInput input) : AbstractEntityProcessor(input)
|
||||
{
|
||||
public override EntityType Type => EntityType.Feat;
|
||||
|
||||
public override Feat Object { get; } = new();
|
||||
|
||||
protected override void Add() => Context.Feats.Add(Object);
|
||||
public override void Add() => Context.Feats.Add(Object);
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
@@ -47,6 +47,7 @@ internal class FeatProcessor(AonprdProcessorInput input) : AbstractProcessor(inp
|
||||
Input.GetOptional<JArray>("archetype")?.Select(t => t.ToString()).ToArray() ?? [];
|
||||
|
||||
Archetype[] archetypes = Context
|
||||
// ReSharper disable once EntityFramework.UnsupportedServerSideFunctionCall
|
||||
.Archetypes.Where(a => Pf2eDbContext.LocaleSearchArray(a.Entity.Name, archetypeStrings))
|
||||
// .Where(a => archetypeStrings.Contains(a.Entity.Name.ToString()))
|
||||
.ToArray();
|
||||
@@ -56,7 +57,7 @@ internal class FeatProcessor(AonprdProcessorInput input) : AbstractProcessor(inp
|
||||
Object.Category = ActionCategory.Archetype;
|
||||
}
|
||||
|
||||
foreach (Archetype? archetype in archetypes)
|
||||
foreach (Archetype archetype in archetypes)
|
||||
{
|
||||
Object.Archetypes.Add(archetype);
|
||||
|
||||
|
||||
+2
-7
@@ -4,16 +4,11 @@ using Pf2eModel.Model.Structure;
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Types;
|
||||
|
||||
[AonprdProcessor("language")]
|
||||
internal class LanguageProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
|
||||
internal class LanguageProcessor(AonprdProcessorInput input) : AbstractEntityProcessor(input)
|
||||
{
|
||||
public override EntityType Type => EntityType.Language;
|
||||
|
||||
public override Language Object { get; } = new();
|
||||
|
||||
protected override void Add() => Context.Languages.Add(Object);
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
base.Process();
|
||||
}
|
||||
public override void Add() => Context.Languages.Add(Object);
|
||||
}
|
||||
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel.Model.Common;
|
||||
using Pf2eModel.Model.Enum;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Types;
|
||||
|
||||
[AonprdProcessor("skill", new string[] { })]
|
||||
internal class TrainingProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
|
||||
{
|
||||
public override EntityType Type => EntityType.Unknown;
|
||||
|
||||
public override IEntity? Object => null;
|
||||
|
||||
protected override void Add() { }
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
// base.Process();
|
||||
|
||||
Training training = new()
|
||||
{
|
||||
Name = Input.GetRequired<string>("name"),
|
||||
Type = TrainingType.Skill,
|
||||
};
|
||||
|
||||
Context.Trainings.Add(training);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -3,14 +3,14 @@ using Pf2eModel.Model.Structure;
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors.Types;
|
||||
|
||||
[AonprdProcessor("trait", new string[] { })]
|
||||
internal class TraitProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
|
||||
[AonprdProcessor("trait", ["external"])]
|
||||
internal class TraitProcessor(AonprdProcessorInput input) : AbstractEntityProcessor(input)
|
||||
{
|
||||
public override EntityType Type => EntityType.Trait;
|
||||
|
||||
public override Trait Object { get; } = new();
|
||||
|
||||
protected override void Add() => Context.Traits.Add(Object);
|
||||
public override void Add() => Context.Traits.Add(Object);
|
||||
|
||||
public override void Process()
|
||||
{
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ internal class CompendiumFolder
|
||||
if (json.TryGetValue("_id", out JToken? id))
|
||||
{
|
||||
// Вложенная папка через _folders.json
|
||||
Id = id!.ToString();
|
||||
Id = id.ToString();
|
||||
Name = json["name"]!.ToString();
|
||||
Path = null;
|
||||
IsContained = true;
|
||||
|
||||
@@ -22,12 +22,12 @@ internal class CompendiumLoader(Pf2EFoundryImporter importer)
|
||||
/// <summary>
|
||||
/// Счётчик папок
|
||||
/// </summary>
|
||||
private int _folderCount = 0;
|
||||
private int _folderCount;
|
||||
|
||||
/// <summary>
|
||||
/// Общее количество элементов в компендиуме
|
||||
/// </summary>
|
||||
public int ItemCount { get; protected set; } = 0;
|
||||
public int ItemCount { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Обработка папок компендиума в поле `packFolders`.
|
||||
@@ -48,7 +48,7 @@ internal class CompendiumLoader(Pf2EFoundryImporter importer)
|
||||
|
||||
if (obj.TryGetValue("packs", out JToken? packs))
|
||||
{
|
||||
foreach (JToken jToken in packs!)
|
||||
foreach (JToken jToken in packs)
|
||||
{
|
||||
string packId = jToken.ToString();
|
||||
CompendiumFolder? child = Collection.GetById(packId);
|
||||
@@ -62,7 +62,7 @@ internal class CompendiumLoader(Pf2EFoundryImporter importer)
|
||||
|
||||
if (obj.TryGetValue("folders", out JToken? innerFolders))
|
||||
{
|
||||
ProcessPackFolders((JArray)innerFolders!, folder);
|
||||
ProcessPackFolders((JArray)innerFolders, folder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ internal class CompendiumLoader(Pf2EFoundryImporter importer)
|
||||
}
|
||||
|
||||
// Поиск _folders.json
|
||||
foreach (CompendiumFolder? parent in Collection.ToList())
|
||||
foreach (CompendiumFolder parent in Collection.ToList())
|
||||
{
|
||||
if (parent.Path is null)
|
||||
{
|
||||
|
||||
+8
-7
@@ -1,5 +1,6 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Pf2eModel;
|
||||
using Pf2eModel.Model;
|
||||
@@ -39,10 +40,7 @@ internal abstract class AbstractProcessor(ProcessorInput input)
|
||||
Entity.IsChecked = false;
|
||||
|
||||
Entity.Slug = Helper.GenerateSlug(Entity.Name[LocaleType.English]);
|
||||
Entity.Rarity = Input.EnumOptional<EntityRarity>(
|
||||
"system.traits.rarity",
|
||||
EntityRarity.Common
|
||||
);
|
||||
Entity.Rarity = Input.EnumOptional("system.traits.rarity", EntityRarity.Common);
|
||||
|
||||
Object.Id = Entity.Id;
|
||||
|
||||
@@ -140,16 +138,19 @@ internal abstract class AbstractProcessor(ProcessorInput input)
|
||||
protected IEnumerable<Trait> GetTraits(IEnumerable<string> names)
|
||||
{
|
||||
List<Trait> result = Context
|
||||
.Traits.Where(t => names.Contains(t.Entity.ToString()))
|
||||
.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.Name.Contains(name)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
Trait trait = new()
|
||||
{
|
||||
Name = name,
|
||||
@@ -159,8 +160,8 @@ internal abstract class AbstractProcessor(ProcessorInput input)
|
||||
};
|
||||
Context.Traits.Add(trait);
|
||||
result.Add(trait);
|
||||
*/
|
||||
}
|
||||
*/
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ internal class ConditionProcessor(ProcessorInput input) : AbstractProcessor(inpu
|
||||
};
|
||||
|
||||
Object.Extra = extra.ToString(Newtonsoft.Json.Formatting.None);
|
||||
Object.Group = Input.EnumOptional<ConditionGroup>("system.group", ConditionGroup.Unknown);
|
||||
Object.Group = Input.EnumOptional("system.group", ConditionGroup.Unknown);
|
||||
|
||||
Context.Conditions.Add(Object);
|
||||
}
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
|
||||
namespace Pf2eDataScrapper.Importers.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Загрузчик данных из git-репозиториев
|
||||
/// </summary>
|
||||
/// <param name="repositoryDirPath"></param>
|
||||
internal class GitRepository(AbstractImporter importer, string url)
|
||||
: AbstractImporterRepository(importer)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ internal class SchemaNode
|
||||
/// <summary>
|
||||
/// Отображаемое имя элемента.
|
||||
/// </summary>
|
||||
public string Name = "";
|
||||
public readonly string Name = "";
|
||||
|
||||
/// <summary>
|
||||
/// Путь к элементу.
|
||||
@@ -21,12 +21,12 @@ internal class SchemaNode
|
||||
/// <summary>
|
||||
/// Родительский элемент.
|
||||
/// </summary>
|
||||
public SchemaNode? Parent = null;
|
||||
public readonly SchemaNode? Parent;
|
||||
|
||||
/// <summary>
|
||||
/// Указание, является ли элемент корневым.
|
||||
/// </summary>
|
||||
public bool Root = false;
|
||||
public readonly bool Root;
|
||||
|
||||
/// <summary>
|
||||
/// Корневой элемент схемы данных.
|
||||
@@ -36,12 +36,12 @@ internal class SchemaNode
|
||||
/// <summary>
|
||||
/// Типы данных, использующиеся в элементе.
|
||||
/// </summary>
|
||||
public List<AbstractSchemaType> Types = [];
|
||||
public readonly List<AbstractSchemaType> Types = [];
|
||||
|
||||
/// <summary>
|
||||
/// Указание, может ли этот элемент отсутсвовать в структуре данных.
|
||||
/// </summary>
|
||||
public bool IsNullable = false;
|
||||
public bool IsNullable;
|
||||
|
||||
/// <summary>
|
||||
/// Объект для определения типа поля в схеме данных.
|
||||
@@ -51,7 +51,7 @@ internal class SchemaNode
|
||||
/// <summary>
|
||||
/// Количество значений, добавленных в тип.
|
||||
/// </summary>
|
||||
public int Values { get; protected set; } = 0;
|
||||
public int Values { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Указание, является ли тип элемента простым.
|
||||
@@ -93,13 +93,10 @@ internal class SchemaNode
|
||||
|
||||
Values++;
|
||||
|
||||
foreach (AbstractSchemaType type in Types)
|
||||
foreach (AbstractSchemaType type in Types.Where(type => type.IsCompatibleValue(value)))
|
||||
{
|
||||
if (type.IsCompatibleValue(value))
|
||||
{
|
||||
type.AddValue(value);
|
||||
return;
|
||||
}
|
||||
type.AddValue(value);
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractSchemaType newType = Resolver.Resolve(this, value);
|
||||
@@ -161,7 +158,7 @@ internal class SchemaNode
|
||||
|
||||
foreach (AbstractSchemaType type in Types)
|
||||
{
|
||||
types.Add(Indent(type?.ToString() ?? ""));
|
||||
types.Add(Indent(type.ToString()));
|
||||
}
|
||||
|
||||
return FormatYaml(result, new() { ["types"] = "- " + string.Join("\r\n- ", types) });
|
||||
@@ -223,19 +220,9 @@ internal class SchemaNode
|
||||
{
|
||||
Dictionary<string, string> result = [];
|
||||
|
||||
foreach (Dictionary<string, string> item in input)
|
||||
foreach (KeyValuePair<string, string> kvp in input.SelectMany(item => item))
|
||||
{
|
||||
foreach (KeyValuePair<string, string> kvp in item)
|
||||
{
|
||||
if (result.ContainsKey(kvp.Key))
|
||||
{
|
||||
result[kvp.Key] = kvp.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
result[kvp.Key] = kvp.Value;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user