Files
Pf2eDataScrapper/Pf2eDataScrapper/Importers/Implementations/Aonprd/SchemaBuilder/AonprdSchemaBuilder.cs
T

172 lines
4.9 KiB
C#

using Konsole;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Compendium;
using Pf2eDataScrapper.SchemaBuilder;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.SchemaBuilder;
/// <summary>
/// Класс создания схемы данных с сайта Архивов Нефеса.
/// </summary>
/// <param name="loader">Загузчик данных с сайта Архивов Нефеса.</param>
internal class AonprdSchemaBuilder(AonprdLoader loader)
{
/// <summary>
/// Загузчик данных с сайта Архивов Нефеса.
/// </summary>
public readonly AonprdLoader Loader = loader;
/// <inheritdoc cref="AonprdLoader.Compendium"/>
public readonly AonprdCompendium Compendium = loader.Compendium;
// public readonly AonprdSchemaTypeResolver Resolver = new();
/// <summary>
/// Дополнительные схемы данных.
/// </summary>
public readonly Dictionary<string, SchemaNode> Schemas = new()
{
["_subclass"] = new() { Path = "_subclass" },
};
/// <summary>
/// Список типов, являющихся подклассами.
/// </summary>
private readonly string[] _subclassSchemaTypes =
[
"research-field",
"apparition",
"practice",
"instinct",
"muse",
"cause",
"tenet",
"doctrine",
"druidic-order",
"methodology",
"element",
"hybrid-study",
"mystery",
"conscious-mind",
"subconscious-mind",
"hunters-edge",
"racket",
"bloodline",
"style",
"implement",
"lesson",
"patron",
"arcane-school",
"arcane-thesis",
"way",
"innovation",
"ikon",
"epithet",
];
/// <summary>
/// Выбор целевого элемента схемы данных для ввода.
/// </summary>
/// <param name="entry">Входные данные.</param>
/// <returns>Целевой элемент схемы данных.</returns>
private SchemaNode GetSchema(AonprdLoader.LoaderEntry entry)
{
string key = entry.Type;
if (Schemas.TryGetValue(key, out SchemaNode? value))
{
return value;
}
value = new()
{
// Resolver = Resolver,
Path = key,
};
Schemas[key] = value;
return value;
}
/// <summary>
/// Построение схемы данных.
/// </summary>
public void BuildSchemas()
{
Console.WriteLine("Building schemas...");
ProgressBar bar = new(Loader.ItemCount);
int i = 0;
foreach (AonprdLoader.LoaderEntry entry in Loader.Entries())
{
bar.Refresh(i++, entry.Type);
GetSchema(entry).AddValue(entry.Json);
if (_subclassSchemaTypes.Contains(entry.Type))
{
Schemas["_subclass"].AddValue(entry.Json);
}
}
bar.Refresh(Loader.ItemCount, "Done!");
}
/// <summary>
/// Сохранение постренных схем данных.
/// </summary>
/// <param name="targetDir">Целевой каталог.</param>
public void Save(string targetDir)
{
Console.WriteLine("Dumping schemas...");
targetDir = Path.Combine(targetDir, Loader.Importer.Slug);
ProgressBar bar = new(Schemas.Count);
int i = 0;
foreach (KeyValuePair<string, SchemaNode> kvp in Schemas)
{
bar.Refresh(i++, kvp.Key);
SaveSchema(targetDir, kvp.Key, kvp.Value);
}
}
/// <summary>
/// Сохранение отдельной схемы данных.
/// </summary>
/// <param name="dir">Целевой каталог.</param>
/// <param name="name">Название схемы.</param>
/// <param name="schema">Сохраняемая схема.</param>
protected void SaveSchema(string dir, string name, SchemaNode schema)
{
char[] invalids = Path.GetInvalidFileNameChars();
string fileName = string.Join(
"_",
schema.Path.Split(invalids, StringSplitOptions.RemoveEmptyEntries)
)
.TrimEnd('.');
string path = Path.Combine(dir, fileName + ".yaml");
string? dirPath = Path.GetDirectoryName(path);
if (dirPath is not null && !Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
using StreamWriter writer = new(path);
schema.Beautify();
writer.WriteLine(
SchemaNode.FormatYaml(
new Dictionary<string, string>()
{
["name"] = name,
["values"] = schema.Values.ToString(),
},
schema.Types[0].GetYamlData()
)
);
}
}