Первая версия обработчиков
This commit is contained in:
+24
@@ -0,0 +1,24 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Slugify;
|
||||||
|
|
||||||
|
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder
|
||||||
|
{
|
||||||
|
internal abstract class AbstractEntityProcessor(JObject input) : AbstractProcessor(input)
|
||||||
|
{
|
||||||
|
public abstract string DbType { get; }
|
||||||
|
|
||||||
|
public override void Process()
|
||||||
|
{
|
||||||
|
Add("name", "name");
|
||||||
|
Add("img", "img");
|
||||||
|
Add("description", "system.description.value");
|
||||||
|
Add("description_gm", "system.description.gm");
|
||||||
|
Add("type", DbType);
|
||||||
|
Add("rarity", "system.traits.rarity");
|
||||||
|
|
||||||
|
SlugHelper sh = new();
|
||||||
|
Data.Add("slug", sh.GenerateSlug(Data["name"]?.ToString() ?? throw new NullReferenceException("'name' is null")));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Npgsql;
|
||||||
|
|
||||||
|
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder
|
||||||
|
{
|
||||||
|
internal abstract class AbstractProcessor(JObject input)
|
||||||
|
{
|
||||||
|
public readonly JObject Input = input;
|
||||||
|
|
||||||
|
public Pf2eDatabase Database = Pf2eDatabase.Instance;
|
||||||
|
|
||||||
|
public DataBuilderHelper Helper = DataBuilderHelper.Instance;
|
||||||
|
|
||||||
|
public abstract string Table { get; }
|
||||||
|
|
||||||
|
public Dictionary<string, object?> Data = [];
|
||||||
|
|
||||||
|
protected void Add(string key, string path)
|
||||||
|
{
|
||||||
|
Data.Add(key, DataBuilderHelper.JsonGet(Input, path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void Process();
|
||||||
|
|
||||||
|
public int Save()
|
||||||
|
{
|
||||||
|
return Helper.Insert(Table, Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Npgsql;
|
||||||
|
|
||||||
|
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder
|
||||||
|
{
|
||||||
|
internal class DataBuilderHelper
|
||||||
|
{
|
||||||
|
public Pf2eDatabase Database = Pf2eDatabase.Instance;
|
||||||
|
|
||||||
|
private DataBuilderHelper()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public NpgsqlCommand PrepareInsert(string table, Dictionary<string, object?> data, bool returnId)
|
||||||
|
{
|
||||||
|
List<string> columns = [];
|
||||||
|
List<string> patterns = [];
|
||||||
|
|
||||||
|
foreach (var key in data.Keys)
|
||||||
|
{
|
||||||
|
columns.Add(key);
|
||||||
|
patterns.Add($":{key.ToUpper()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
string dml = $"INSERT INTO {table} (\"{string.Join("\", \"", columns)}\") VALUES ({string.Join(", ", patterns)})" + (returnId ? " RETURNING id" : "");
|
||||||
|
|
||||||
|
NpgsqlCommand cmd = Database.GetCommand(dml);
|
||||||
|
foreach (var kvp in data)
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue(":" + kvp.Key.ToUpper(), kvp.Value ?? DBNull.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(cmd.CommandText);
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Insert(string table, Dictionary<string, object?> data)
|
||||||
|
{
|
||||||
|
var cmd = PrepareInsert(table, data, true);
|
||||||
|
return (int)(cmd.ExecuteScalar() ?? throw new Exception("Not a number"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InsertBlind(string table, Dictionary<string, object?> data)
|
||||||
|
{
|
||||||
|
var cmd = PrepareInsert(table, data, false);
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static object? JsonGet(JObject root, string path)
|
||||||
|
{
|
||||||
|
var token = root.SelectToken(path);
|
||||||
|
|
||||||
|
if (token == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.Type == JTokenType.String)
|
||||||
|
{
|
||||||
|
return token.ToString();
|
||||||
|
}
|
||||||
|
else if (token.Type == JTokenType.Integer)
|
||||||
|
{
|
||||||
|
return token.ToObject<int>();
|
||||||
|
}
|
||||||
|
else if (token.Type == JTokenType.Float)
|
||||||
|
{
|
||||||
|
return token.ToObject<float>();
|
||||||
|
}
|
||||||
|
else if (token.Type == JTokenType.Boolean)
|
||||||
|
{
|
||||||
|
return token.ToObject<bool>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return token.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataBuilderHelper Instance = new();
|
||||||
|
}
|
||||||
|
}
|
||||||
+85
@@ -0,0 +1,85 @@
|
|||||||
|
using Konsole;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder
|
||||||
|
{
|
||||||
|
internal class PF2eFoundryDataBuilder
|
||||||
|
{
|
||||||
|
public Pf2eDatabase Database = Pf2eDatabase.Instance;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Загрузчик данных.
|
||||||
|
/// </summary>
|
||||||
|
public readonly CompendiumLoader Loader;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Коллекция папок компендиума.
|
||||||
|
/// </summary>
|
||||||
|
public CompendiumFolderCollection Collection => Loader.Collection;
|
||||||
|
|
||||||
|
public Dictionary<string, ConstructorInfo> Processors = [];
|
||||||
|
|
||||||
|
public PF2eFoundryDataBuilder(CompendiumLoader loader)
|
||||||
|
{
|
||||||
|
Loader = loader;
|
||||||
|
PrepareProcessors();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrepareProcessors()
|
||||||
|
{
|
||||||
|
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
|
||||||
|
{
|
||||||
|
if (type.GetCustomAttributes(typeof(Pf2eTypeProcessor), true).Length > 0)
|
||||||
|
{
|
||||||
|
var attribute = type.GetCustomAttribute<Pf2eTypeProcessor>();
|
||||||
|
Processors.Add(attribute!.Type, type.GetConstructor(new[] { typeof(JObject) })!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractProcessor? GetProcessor(string type, JObject input)
|
||||||
|
{
|
||||||
|
if (Processors.TryGetValue(type, out var constructor))
|
||||||
|
{
|
||||||
|
return (AbstractProcessor)constructor.Invoke([input]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TruncateTables()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Truncating all old data...");
|
||||||
|
|
||||||
|
Database.ExecuteCommand($"SELECT f_truncate_tables();");
|
||||||
|
|
||||||
|
Console.WriteLine("Truncation completed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Build()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Building data...");
|
||||||
|
|
||||||
|
var bar = new ProgressBar(Loader.ItemCount);
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
foreach (var entry in Loader.Enrties())
|
||||||
|
{
|
||||||
|
bar.Refresh(i++, $"{entry.Folder.Name}/{entry.File.Name}");
|
||||||
|
|
||||||
|
var processor = GetProcessor($"{entry.Folder.Type}.{entry.Type}", entry.Json);
|
||||||
|
if (processor is null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
processor.Process();
|
||||||
|
processor.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bar.Refresh(Loader.ItemCount, "Done!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
|
internal class Pf2eTypeProcessor(string type) : Attribute
|
||||||
|
{
|
||||||
|
public readonly string Type = type;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder.Processors
|
||||||
|
{
|
||||||
|
[Pf2eTypeProcessor("Item.condition")]
|
||||||
|
internal class ConditionProcessor(JObject input) : AbstractEntityProcessor(input)
|
||||||
|
{
|
||||||
|
public override string Table => "condition";
|
||||||
|
|
||||||
|
public override string DbType => "condition";
|
||||||
|
|
||||||
|
public override void Process()
|
||||||
|
{
|
||||||
|
base.Process();
|
||||||
|
|
||||||
|
Add("group", "system.group");
|
||||||
|
|
||||||
|
JObject extra = new()
|
||||||
|
{
|
||||||
|
{ "duration", Input.SelectToken("duration") },
|
||||||
|
{ "overrides", Input.SelectToken("overrides") },
|
||||||
|
{ "references", Input.SelectToken("references") },
|
||||||
|
{ "value", Input.SelectToken("value") }
|
||||||
|
};
|
||||||
|
|
||||||
|
Data.Add("extra", extra.ToString(Newtonsoft.Json.Formatting.Indented));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user