using System; using System.Collections.Generic; using System.IO; using Newtonsoft.Json.Linq; using Pf2e.Scrapper.Helpers; using Pf2e.Scrapper.Importers; using Pf2e.Scrapper.Processors.Definitions; namespace Pf2e.Scrapper.SchemaBuilder; public abstract class AbstractSchemaBuildProcessor : IProcessor { /// /// Связаный компендиум /// protected abstract AbstractCompendium Compendium { get; } /// protected abstract ProcessProgress Progress { get; } /// /// Определитель типов данных. /// protected abstract TypeResolver Resolver { get; } /// /// Путь к каталогу для сохранения вывода. /// protected abstract string SavePath { get; } /// /// Набор схем данных. /// protected Dictionary Schemas { get; } = []; /// /// Получить список названий элементов структуры данных на основе вводимого элемента. /// /// Вводимый элемент /// Коллекция названий элементов структуры данных/ protected abstract ICollection GetSchemaNodes(AbstractCompendiumItem item); /// /// Построение схемы данных. /// public void Process() { Progress.Local.Reset(Compendium.Count()); foreach ((AbstractCompendiumItem reference, JObject json) in Compendium.Iterate()) { Progress.Local.Start(reference.ToString()); foreach (string nodeName in GetSchemaNodes(reference)) { if (!Schemas.TryGetValue(nodeName, out SchemaNode? node)) { node = new() { Path = nodeName, Resolver = Resolver }; Schemas.Add(nodeName, node); } node.AddValue(json); } Progress.Local.End(); } Progress.Local.Complete(); } /// /// Сохранение постренных схем данных. /// public void Save() { string targetDir = SavePath; foreach (KeyValuePair kvp in Schemas) { SaveSchema(targetDir, kvp.Key, kvp.Value); } } /// /// Сохранение отдельной схемы данных. /// /// Целевой каталог. /// Название схемы. /// Сохраняемая схема. 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() { ["name"] = name, ["values"] = schema.Values.ToString(), }, schema.Types[0].GetYamlData() ) ); } }