Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28d4c52c5c | ||
|
|
379a73edf4 |
@@ -1,26 +1,39 @@
|
|||||||
using System;
|
using dotenv.net;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using dotenv.net;
|
|
||||||
using dotenv.net.Utilities;
|
using dotenv.net.Utilities;
|
||||||
|
|
||||||
namespace Pf2eDataScrapper
|
namespace Pf2eDataScrapper
|
||||||
{
|
{
|
||||||
internal class EnvSettings
|
/// <summary>
|
||||||
|
/// Класс настроек.
|
||||||
|
/// </summary>
|
||||||
|
internal static class EnvSettings
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Загрузка файла настроек `.env`.
|
||||||
|
/// </summary>
|
||||||
public static void Load()
|
public static void Load()
|
||||||
{
|
{
|
||||||
DotEnv.Load();
|
DotEnv.Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Путь к папке с входными данными.
|
||||||
|
/// </summary>
|
||||||
public static string DataDirPath => EnvReader.GetStringValue("DATA_DIR");
|
public static string DataDirPath => EnvReader.GetStringValue("DATA_DIR");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Папка в входными данными.
|
||||||
|
/// </summary>
|
||||||
public static DirectoryInfo DataDir => new(DataDirPath);
|
public static DirectoryInfo DataDir => new(DataDirPath);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Путь к папке для сохранения результатов.
|
||||||
|
/// </summary>
|
||||||
public static string OutputDirPath => EnvReader.GetStringValue("OUTPUT_DIR");
|
public static string OutputDirPath => EnvReader.GetStringValue("OUTPUT_DIR");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Папка для сохранения результатов.
|
||||||
|
/// </summary>
|
||||||
public static string OutputDir => new(OutputDirPath);
|
public static string OutputDir => new(OutputDirPath);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
using System;
|
namespace Pf2eDataScrapper.Importers
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.Importers
|
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Абстрактный класс импортёра
|
||||||
|
/// </summary>
|
||||||
internal abstract class AbstractImporter
|
internal abstract class AbstractImporter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -28,7 +25,14 @@ namespace Pf2eDataScrapper.Importers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Dir => Path.Combine(EnvSettings.DataDirPath, Slug);
|
public string Dir => Path.Combine(EnvSettings.DataDirPath, Slug);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Метод подготовки данных для импорта
|
||||||
|
/// </summary>
|
||||||
public abstract void Prepare();
|
public abstract void Prepare();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Импорт данных
|
||||||
|
/// </summary>
|
||||||
public abstract void Import();
|
public abstract void Import();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,30 @@
|
|||||||
using System;
|
using System.Diagnostics;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.Importers
|
namespace Pf2eDataScrapper.Importers
|
||||||
{
|
{
|
||||||
internal class GitLoader(string DataDirPath)
|
/// <summary>
|
||||||
|
/// Загрузчик данных из git-репозиториев
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="repositoryDirPath"></param>
|
||||||
|
internal class GitLoader(string repositoryDirPath)
|
||||||
{
|
{
|
||||||
public readonly string DataDirPath = DataDirPath;
|
/// <summary>
|
||||||
public DirectoryInfo DataDir = new(DataDirPath);
|
/// Путь к директории репозитория
|
||||||
|
/// </summary>
|
||||||
|
public readonly string RepositoryDirPath = repositoryDirPath;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Директория репозитория
|
||||||
|
/// </summary>
|
||||||
|
public DirectoryInfo RepositoryDir = new(repositoryDirPath);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Обновление импортёра
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="importer"></param>
|
||||||
public void UpdateImporter(AbstractImporter importer)
|
public void UpdateImporter(AbstractImporter importer)
|
||||||
{
|
{
|
||||||
string gitPath = Path.Combine(DataDirPath, importer.Slug);
|
var gitPath = Path.Combine(RepositoryDirPath, importer.Slug);
|
||||||
|
|
||||||
if (Directory.Exists(gitPath))
|
if (Directory.Exists(gitPath))
|
||||||
{
|
{
|
||||||
@@ -38,7 +48,7 @@ namespace Pf2eDataScrapper.Importers
|
|||||||
StartInfo = new ProcessStartInfo()
|
StartInfo = new ProcessStartInfo()
|
||||||
{
|
{
|
||||||
FileName = "git",
|
FileName = "git",
|
||||||
WorkingDirectory = DataDirPath,
|
WorkingDirectory = RepositoryDirPath,
|
||||||
Arguments = $"clone {importer.GitUrl} {importer.Slug}",
|
Arguments = $"clone {importer.GitUrl} {importer.Slug}",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+4
-7
@@ -1,11 +1,8 @@
|
|||||||
using System;
|
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Тип документов компендиума.
|
||||||
|
/// </summary>
|
||||||
internal enum CompendiumDocumentType
|
internal enum CompendiumDocumentType
|
||||||
{
|
{
|
||||||
Actor,
|
Actor,
|
||||||
|
|||||||
+37
-8
@@ -1,32 +1,52 @@
|
|||||||
using System;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Папка компендиума.
|
||||||
|
/// </summary>
|
||||||
internal class CompendiumFolder
|
internal class CompendiumFolder
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Идентификатор папки.
|
||||||
|
/// </summary>
|
||||||
public readonly string Id;
|
public readonly string Id;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Название папки.
|
||||||
|
/// </summary>
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Путь к папке.
|
||||||
|
/// </summary>
|
||||||
public readonly string? Path;
|
public readonly string? Path;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Указатель, что папка содержится в других папках.
|
||||||
|
/// </summary>
|
||||||
public readonly bool IsContained;
|
public readonly bool IsContained;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Родительская папка.
|
||||||
|
/// </summary>
|
||||||
public CompendiumFolder? Parent;
|
public CompendiumFolder? Parent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Тип документов в папке.
|
||||||
|
/// </summary>
|
||||||
public readonly CompendiumDocumentType Type;
|
public readonly CompendiumDocumentType Type;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Конструктор папки компендиума из JSON-объекта.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="json"></param>
|
||||||
public CompendiumFolder(JObject json)
|
public CompendiumFolder(JObject json)
|
||||||
{
|
{
|
||||||
if (json.ContainsKey("_id"))
|
if (json.TryGetValue("_id", out var id))
|
||||||
{
|
{
|
||||||
// Вложенная папка через _folders.json
|
// Вложенная папка через _folders.json
|
||||||
Id = json["_id"]!.ToString();
|
Id = id!.ToString();
|
||||||
Name = json["name"]!.ToString();
|
Name = json["name"]!.ToString();
|
||||||
Path = null;
|
Path = null;
|
||||||
IsContained = true;
|
IsContained = true;
|
||||||
@@ -43,6 +63,11 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
|||||||
Type = (CompendiumDocumentType)Enum.Parse(typeof(CompendiumDocumentType), json["type"]!.ToString());
|
Type = (CompendiumDocumentType)Enum.Parse(typeof(CompendiumDocumentType), json["type"]!.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Конструктор папки компендиума.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">Идентификатор папки.</param>
|
||||||
|
/// <param name="name">Название папки.</param>
|
||||||
public CompendiumFolder(string id, string name)
|
public CompendiumFolder(string id, string name)
|
||||||
{
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
@@ -51,6 +76,10 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
|||||||
IsContained = false;
|
IsContained = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Строковое представление данных о папки компендиума.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Строковое представление данных о папки компендиума.</returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"CompendiumFolder([Id={Id}][Type={Type}][Name={Name}][Path={Path}][Parent={Parent?.Name ?? "null"}])";
|
return $"CompendiumFolder([Id={Id}][Type={Type}][Name={Name}][Path={Path}][Parent={Parent?.Name ?? "null"}])";
|
||||||
|
|||||||
+9
-8
@@ -1,14 +1,15 @@
|
|||||||
using System;
|
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Коллекция папок компендиума
|
||||||
|
/// </summary>
|
||||||
internal class CompendiumFolderCollection : List<CompendiumFolder>
|
internal class CompendiumFolderCollection : List<CompendiumFolder>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Получение папки по идентификатору
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">Искомый идентификатор</param>
|
||||||
|
/// <returns>Искомая папка</returns>
|
||||||
public CompendiumFolder? GetById(string id)
|
public CompendiumFolder? GetById(string id)
|
||||||
{
|
{
|
||||||
return this.FirstOrDefault(x => x.Id == id);
|
return this.FirstOrDefault(x => x.Id == id);
|
||||||
|
|||||||
+38
-7
@@ -1,27 +1,46 @@
|
|||||||
using Konsole;
|
using Konsole;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Pf2eDataScrapper.SchemaBuilder;
|
using Pf2eDataScrapper.SchemaBuilder;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Класс построения схемы компендиумов.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="loader">Загрузчик данных.</param>
|
||||||
internal class CompendiumSchemaBuilder(CompendiumLoader loader)
|
internal class CompendiumSchemaBuilder(CompendiumLoader loader)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Загрузчик данных.
|
||||||
|
/// </summary>
|
||||||
public CompendiumLoader Loader = loader;
|
public CompendiumLoader Loader = loader;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Коллекция папок компендиума.
|
||||||
|
/// </summary>
|
||||||
public CompendiumFolderCollection Collection = loader.Collection;
|
public CompendiumFolderCollection Collection = loader.Collection;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Объект для определения типов полей в компендиумах PF2E.
|
||||||
|
/// </summary>
|
||||||
public CompendiumSchemaTypeResolver Resolver = new();
|
public CompendiumSchemaTypeResolver Resolver = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Схемы данных по папкам.
|
||||||
|
/// </summary>
|
||||||
public Dictionary<CompendiumFolder, SchemaNode> PackSchemas = [];
|
public Dictionary<CompendiumFolder, SchemaNode> PackSchemas = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Схемы данных по типам.
|
||||||
|
/// </summary>
|
||||||
public Dictionary<string, SchemaNode> TypeSchemas = [];
|
public Dictionary<string, SchemaNode> TypeSchemas = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение набора схем, к которым относится проверяемый объект.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folder">Папка компендиума, в которой находится объект.</param>
|
||||||
|
/// <param name="itemType">Указанный тип объекта.</param>
|
||||||
|
/// <returns></returns>
|
||||||
protected List<SchemaNode> GetItemSchemas(CompendiumFolder folder, string? itemType)
|
protected List<SchemaNode> GetItemSchemas(CompendiumFolder folder, string? itemType)
|
||||||
{
|
{
|
||||||
if (!PackSchemas.ContainsKey(folder))
|
if (!PackSchemas.ContainsKey(folder))
|
||||||
@@ -47,6 +66,9 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
|||||||
return [PackSchemas[folder], TypeSchemas[key]];
|
return [PackSchemas[folder], TypeSchemas[key]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Построение схем данных.
|
||||||
|
/// </summary>
|
||||||
public void BuildSchemas()
|
public void BuildSchemas()
|
||||||
{
|
{
|
||||||
Console.WriteLine("Building schemas...");
|
Console.WriteLine("Building schemas...");
|
||||||
@@ -90,6 +112,10 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
|||||||
bar.Refresh(Loader.ItemCount, "Done!");
|
bar.Refresh(Loader.ItemCount, "Done!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Сохранение данных.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="targetDir">Папка для сохранения.</param>
|
||||||
public void Save(string targetDir)
|
public void Save(string targetDir)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Dumping schemas...");
|
Console.WriteLine("Dumping schemas...");
|
||||||
@@ -127,6 +153,12 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
|||||||
Console.WriteLine("Done!");
|
Console.WriteLine("Done!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Сохранение конкретной схемы.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dir">Корневая папка для сохранения этой категории схем.</param>
|
||||||
|
/// <param name="name">Название сохраняемой схемы.</param>
|
||||||
|
/// <param name="schema">Сохраняемая схема.</param>
|
||||||
protected void SaveSchema(string dir, string name, SchemaNode schema)
|
protected void SaveSchema(string dir, string name, SchemaNode schema)
|
||||||
{
|
{
|
||||||
var invalids = System.IO.Path.GetInvalidFileNameChars();
|
var invalids = System.IO.Path.GetInvalidFileNameChars();
|
||||||
@@ -134,7 +166,6 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium
|
|||||||
|
|
||||||
var path = Path.Combine(dir, fileName + ".txt");
|
var path = Path.Combine(dir, fileName + ".txt");
|
||||||
|
|
||||||
|
|
||||||
var dirPath = Path.GetDirectoryName(path);
|
var dirPath = Path.GetDirectoryName(path);
|
||||||
|
|
||||||
if (!Directory.Exists(dirPath))
|
if (!Directory.Exists(dirPath))
|
||||||
|
|||||||
@@ -1,22 +1,39 @@
|
|||||||
using System.Reflection.PortableExecutable;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Konsole;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium;
|
using Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.Compendium;
|
||||||
using Pf2eDataScrapper.SchemaBuilder;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry
|
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry
|
||||||
{
|
{
|
||||||
internal class CompendiumLoader(Pf2eFoundryImporter importer)
|
/// <summary>
|
||||||
|
/// Загрузчик данных компендиума
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="importer">Импортёр</param>
|
||||||
|
internal class CompendiumLoader(Pf2EFoundryImporter importer)
|
||||||
{
|
{
|
||||||
public readonly Pf2eFoundryImporter Importer = importer;
|
/// <summary>
|
||||||
|
/// Импортёр
|
||||||
|
/// </summary>
|
||||||
|
public readonly Pf2EFoundryImporter Importer = importer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Набор папок компендиума
|
||||||
|
/// </summary>
|
||||||
public CompendiumFolderCollection Collection = [];
|
public CompendiumFolderCollection Collection = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Счётчик папок
|
||||||
|
/// </summary>
|
||||||
private int _folderCount = 0;
|
private int _folderCount = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Общее количество элементов в компендиуме
|
||||||
|
/// </summary>
|
||||||
public int ItemCount { get; protected set; } = 0;
|
public int ItemCount { get; protected set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Обработка папок компендиума в поле `packFolders`.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folders"></param>
|
||||||
|
/// <param name="parent"></param>
|
||||||
protected void ProcessPackFolders(JArray folders, CompendiumFolder? parent)
|
protected void ProcessPackFolders(JArray folders, CompendiumFolder? parent)
|
||||||
{
|
{
|
||||||
foreach (var token in folders)
|
foreach (var token in folders)
|
||||||
@@ -53,6 +70,9 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Подготовка набора папок компендиума
|
||||||
|
/// </summary>
|
||||||
public void Prepare()
|
public void Prepare()
|
||||||
{
|
{
|
||||||
using var systemFile = new StreamReader(Path.Combine(Importer.Dir, "static", "system.json"));
|
using var systemFile = new StreamReader(Path.Combine(Importer.Dir, "static", "system.json"));
|
||||||
@@ -104,10 +124,5 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry
|
|||||||
|
|
||||||
Console.WriteLine($"Total items: {ItemCount}");
|
Console.WriteLine($"Total items: {ItemCount}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Run()
|
|
||||||
{
|
|
||||||
this.Prepare();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,52 @@
|
|||||||
using System;
|
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry
|
|
||||||
{
|
{
|
||||||
internal class Pf2eFoundryImporter : AbstractImporter
|
/// <summary>
|
||||||
|
/// Импортёр для модуля Pf2e FoundryVTT.
|
||||||
|
/// </summary>
|
||||||
|
internal class Pf2EFoundryImporter : AbstractImporter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Отображаемое имя импортёра
|
/// Отображаемое имя импортёра.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override string Name => "Pf2e FoundryVTT module";
|
public override string Name => "Pf2e FoundryVTT module";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Короткое имя импортёра
|
/// Короткое имя импортёра.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override string Slug => "pf2e";
|
public override string Slug => "pf2e";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ссылка на git-репозиторий для клонирования
|
/// Ссылка на git-репозиторий для клонирования.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override string GitUrl => "https://github.com/foundryvtt/pf2e.git";
|
public override string GitUrl => "https://github.com/foundryvtt/pf2e.git";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Загрузчик данных компендиума.
|
||||||
|
/// </summary>
|
||||||
public CompendiumLoader Loader { get; }
|
public CompendiumLoader Loader { get; }
|
||||||
|
|
||||||
public Pf2eFoundryImporter()
|
/// <summary>
|
||||||
|
/// Конструктор импортёра.
|
||||||
|
/// </summary>
|
||||||
|
public Pf2EFoundryImporter()
|
||||||
{
|
{
|
||||||
Loader = new CompendiumLoader(this);
|
Loader = new CompendiumLoader(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Метод подготовки данных для импорта.
|
||||||
|
/// </summary>
|
||||||
public override void Prepare()
|
public override void Prepare()
|
||||||
{
|
{
|
||||||
Loader.Prepare();
|
Loader.Prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Импорт данных.
|
||||||
|
/// </summary>
|
||||||
public override void Import()
|
public override void Import()
|
||||||
{
|
{
|
||||||
Loader.Run();
|
Loader.Prepare();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ EnvSettings.Load();
|
|||||||
|
|
||||||
Console.WriteLine("Hello, World!");
|
Console.WriteLine("Hello, World!");
|
||||||
|
|
||||||
//var loader = new GitLoader(EnvSettings.DataDirPath);
|
//var loader = new GitLoader(EnvSettings.RepositoryDirPath);
|
||||||
|
|
||||||
|
|
||||||
var importer = new Pf2eFoundryImporter();
|
var importer = new Pf2EFoundryImporter();
|
||||||
|
|
||||||
//loader.UpdateImporter(importer);
|
//loader.UpdateImporter(importer);
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +1,76 @@
|
|||||||
using System;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Pf2eDataScrapper.SchemaBuilder.Types;
|
using Pf2eDataScrapper.SchemaBuilder.Types;
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.SchemaBuilder
|
namespace Pf2eDataScrapper.SchemaBuilder
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Элемент схемы данных.
|
||||||
|
/// </summary>
|
||||||
internal class SchemaNode
|
internal class SchemaNode
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Отображаемое имя элемента.
|
||||||
|
/// </summary>
|
||||||
public string Name = "";
|
public string Name = "";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Путь к элементу.
|
||||||
|
/// </summary>
|
||||||
public string Path = "";
|
public string Path = "";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Родительский элемент.
|
||||||
|
/// </summary>
|
||||||
public SchemaNode? Parent = null;
|
public SchemaNode? Parent = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Указание, является ли элемент корневым.
|
||||||
|
/// </summary>
|
||||||
public bool Root = false;
|
public bool Root = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Корневой элемент схемы данных.
|
||||||
|
/// </summary>
|
||||||
public SchemaNode RootNode => Root ? this : Parent!.RootNode;
|
public SchemaNode RootNode => Root ? this : Parent!.RootNode;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Типы данных, использующиеся в элементе.
|
||||||
|
/// </summary>
|
||||||
public List<AbstractSchemaType> Types = [];
|
public List<AbstractSchemaType> Types = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Указание, может ли этот элемент отсутсвовать в структуре данных.
|
||||||
|
/// </summary>
|
||||||
public bool IsNullable = false;
|
public bool IsNullable = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Объект для определения типа поля в схеме данных.
|
||||||
|
/// </summary>
|
||||||
public TypeResolver Resolver = new();
|
public TypeResolver Resolver = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Количество значений, добавленных в тип.
|
||||||
|
/// </summary>
|
||||||
public int Values { get; protected set; } = 0;
|
public int Values { get; protected set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Указание, является ли тип элемента простым.
|
||||||
|
/// </summary>
|
||||||
public bool IsSimple => Types.Count == 1;
|
public bool IsSimple => Types.Count == 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Конструктор корневого элемента.
|
||||||
|
/// </summary>
|
||||||
public SchemaNode()
|
public SchemaNode()
|
||||||
{
|
{
|
||||||
this.Root = true;
|
this.Root = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Конструктор элемента схемы данных.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent">Родительский элемент.</param>
|
||||||
|
/// <param name="name">Имя элемента.</param>
|
||||||
public SchemaNode(SchemaNode parent, string name)
|
public SchemaNode(SchemaNode parent, string name)
|
||||||
{
|
{
|
||||||
this.Parent = parent;
|
this.Parent = parent;
|
||||||
@@ -44,6 +79,10 @@ namespace Pf2eDataScrapper.SchemaBuilder
|
|||||||
this.Resolver = parent.Resolver;
|
this.Resolver = parent.Resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Добавление нового возможного значения.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Добавляемое значение</param>
|
||||||
public void AddValue(JToken? value)
|
public void AddValue(JToken? value)
|
||||||
{
|
{
|
||||||
if (value is null || Resolver.TokenType(value) == JTokenType.Null)
|
if (value is null || Resolver.TokenType(value) == JTokenType.Null)
|
||||||
@@ -68,6 +107,10 @@ namespace Pf2eDataScrapper.SchemaBuilder
|
|||||||
Types.Add(newType);
|
Types.Add(newType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение строкового представоения типа элемента.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Строковое представоение типа элемента</returns>
|
||||||
public string GetTypeName()
|
public string GetTypeName()
|
||||||
{
|
{
|
||||||
if (IsSimple)
|
if (IsSimple)
|
||||||
@@ -75,11 +118,15 @@ namespace Pf2eDataScrapper.SchemaBuilder
|
|||||||
return Types[0].GetTypeName();
|
return Types[0].GetTypeName();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> typeNames = Types.Select(t => t.GetTypeName()).ToList();
|
var typeNames = Types.Select(t => t.GetTypeName()).ToList();
|
||||||
|
|
||||||
return string.Join("|", typeNames);
|
return string.Join("|", typeNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Полное строковое представление элемента.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Строковое представление элемента.</returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
if (IsSimple)
|
if (IsSimple)
|
||||||
@@ -97,6 +144,9 @@ namespace Pf2eDataScrapper.SchemaBuilder
|
|||||||
return string.Join("\n" + AbstractSchemaType.Tab, result);
|
return string.Join("\n" + AbstractSchemaType.Tab, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Подготовка элемента к красивому представлению.
|
||||||
|
/// </summary>
|
||||||
public void Beautify()
|
public void Beautify()
|
||||||
{
|
{
|
||||||
foreach (var type in Types)
|
foreach (var type in Types)
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
using System;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Pf2eDataScrapper.SchemaBuilder.Types;
|
using Pf2eDataScrapper.SchemaBuilder.Types;
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.SchemaBuilder
|
namespace Pf2eDataScrapper.SchemaBuilder
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Класс для определения типа поля в схеме данных.
|
||||||
|
/// </summary>
|
||||||
internal class TypeResolver
|
internal class TypeResolver
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Проверка соответствия пути.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">Элемент, путь которого проверяется.</param>
|
||||||
|
/// <param name="path">Проверяемый путь. Допускается использование `*` в местах, где допускается любое значение.</param>
|
||||||
|
/// <returns>`true`, если `node.Path` соответсвует указанному в `path` значению.</returns>
|
||||||
public bool CheckPath(SchemaNode node, string path)
|
public bool CheckPath(SchemaNode node, string path)
|
||||||
{
|
{
|
||||||
if (!path.Contains("*"))
|
if (!path.Contains("*"))
|
||||||
@@ -27,12 +31,23 @@ namespace Pf2eDataScrapper.SchemaBuilder
|
|||||||
|
|
||||||
return !pathParts.Where((t, i) => t != "*" && t != nodeParts[i]).Any();
|
return !pathParts.Where((t, i) => t != "*" && t != nodeParts[i]).Any();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проверка соответствия пути.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">Элемент, путь которого проверяется.</param>
|
||||||
|
/// <param name="paths">Проверяемые пути. Допускается использование `*` в местах, где допускается любое значение.</param>
|
||||||
|
/// <returns>`true`, если `node.Path` соответсвует хотя бы одному указанному в `paths` значению.</returns>
|
||||||
public bool CheckPath(SchemaNode node, ICollection<string> paths)
|
public bool CheckPath(SchemaNode node, ICollection<string> paths)
|
||||||
{
|
{
|
||||||
return paths.Any(path => CheckPath(node, path));
|
return paths.Any(path => CheckPath(node, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение типа значения.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Значение.</param>
|
||||||
|
/// <returns>Типа значения.</returns>
|
||||||
public JTokenType TokenType(JToken? value)
|
public JTokenType TokenType(JToken? value)
|
||||||
{
|
{
|
||||||
if (value is null || value.Type is JTokenType.Null or JTokenType.Undefined or JTokenType.None)
|
if (value is null || value.Type is JTokenType.Null or JTokenType.Undefined or JTokenType.None)
|
||||||
@@ -43,13 +58,23 @@ namespace Pf2eDataScrapper.SchemaBuilder
|
|||||||
return value.Type;
|
return value.Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Определение типа поля.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">Поле схемы данных, для которого создаётся тип.</param>
|
||||||
|
/// <param name="value">Добавляемое значение.</param>
|
||||||
|
/// <returns>Новый тип для схемы данных</returns>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// Возникает, если у `value` значение идентично `null`
|
||||||
|
/// (такие значения должны обрабаотываться в `SchemaNode`).
|
||||||
|
/// </exception>
|
||||||
public virtual AbstractSchemaType Resolve(SchemaNode node, JToken? value)
|
public virtual AbstractSchemaType Resolve(SchemaNode node, JToken? value)
|
||||||
{
|
{
|
||||||
var type = TokenType(value);
|
var type = TokenType(value);
|
||||||
|
|
||||||
if (type == JTokenType.Null)
|
if (type == JTokenType.Null)
|
||||||
{
|
{
|
||||||
throw new Exception("Value is null, cannot determine type");
|
throw new ArgumentNullException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return type switch
|
return type switch
|
||||||
|
|||||||
@@ -1,58 +1,76 @@
|
|||||||
using System.ComponentModel.Design.Serialization;
|
using Newtonsoft.Json.Linq;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.SchemaBuilder.Types
|
namespace Pf2eDataScrapper.SchemaBuilder.Types
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Абстрактный тип представоления данных в схеме.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent">Элемент, к которому добавляется тип.</param>
|
||||||
internal abstract class AbstractSchemaType(SchemaNode parent)
|
internal abstract class AbstractSchemaType(SchemaNode parent)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Элемент схемы данных, к которому относится тип.
|
||||||
|
/// </summary>
|
||||||
public SchemaNode Parent = parent;
|
public SchemaNode Parent = parent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Корневой элемент схемы данных.
|
||||||
|
/// </summary>
|
||||||
public SchemaNode Root => Parent.RootNode;
|
public SchemaNode Root => Parent.RootNode;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Объект для определения типа поля в схеме данных.
|
||||||
|
/// </summary>
|
||||||
public TypeResolver Resolver => Root.Resolver;
|
public TypeResolver Resolver => Root.Resolver;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if type is compatible with current type.
|
/// Проверка, что значение совместимо с текущим типом.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">Value to be checked</param>
|
/// <param name="value">Проверяемое значение.</param>
|
||||||
/// <returns>True if value is compatible with current type</returns>
|
/// <returns>`true`, если значение совместимо с текущим типом.</returns>
|
||||||
public abstract bool IsCompatibleValue(JToken value);
|
public abstract bool IsCompatibleValue(JToken value);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add new possible value.
|
/// Добавление нового значения.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">New value</param>
|
/// <param name="value">Новое значение.</param>
|
||||||
public abstract void AddValue(JToken value);
|
public abstract void AddValue(JToken value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Подготовка типа к красивому представлению.
|
||||||
|
/// </summary>
|
||||||
public abstract void Beautify();
|
public abstract void Beautify();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// String representation of type.
|
/// Получение строкового представоения типа элемента.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns>Строковое представоение типа элемента</returns>
|
||||||
public abstract string GetTypeName();
|
public abstract string GetTypeName();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Полное строковое представление элемента.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Строковое представление элемента.</returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"{GetTypeName()} {Parent.Path}";
|
return $"{GetTypeName()} {Parent.Path}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tabulation characters.
|
/// Отступ для строкового представления.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string Tab = " ";
|
public const string Tab = " ";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Limit of elements in list or dictionary to be displayed.
|
/// Предел количество отображаемых элементов.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int ElementLimit = 20;
|
public const int ElementLimit = 10;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indent text.
|
/// Увеличение отступа строки.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">Text to be indented</param>
|
/// <param name="text">Изменяемая строка.</param>
|
||||||
/// <returns>Indented text</returns>
|
/// <returns>Строка с добавленными отступами.</returns>
|
||||||
public static string Indent(string text)
|
public static string Indent(string text)
|
||||||
{
|
{
|
||||||
return text.Replace("\n", "\n" + Tab);
|
return text.Replace("\n", "\n" + Tab);
|
||||||
|
|||||||
@@ -1,28 +1,42 @@
|
|||||||
using System;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Transactions;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.SchemaBuilder.Types
|
namespace Pf2eDataScrapper.SchemaBuilder.Types
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Тип представоления массива в схеме.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent">Элемент, к которому добавляется тип.</param>
|
||||||
internal class ArraySchemaType(SchemaNode parent) : AbstractSchemaType(parent)
|
internal class ArraySchemaType(SchemaNode parent) : AbstractSchemaType(parent)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Минимальное количество элементов в массиве.
|
||||||
|
/// </summary>
|
||||||
public int MinCount = int.MaxValue;
|
public int MinCount = int.MaxValue;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Максимальное количество элементов в массиве.
|
||||||
|
/// </summary>
|
||||||
public int MaxCount = int.MinValue;
|
public int MaxCount = int.MinValue;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Схема элемента массива.
|
||||||
|
/// </summary>
|
||||||
protected SchemaNode ElementSchema = new(parent, "[]");
|
protected SchemaNode ElementSchema = new(parent, "[]");
|
||||||
|
|
||||||
protected List<JToken?> Values = [];
|
/// <summary>
|
||||||
|
/// Проверка, что значение совместимо с текущим типом.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Проверяемое значение.</param>
|
||||||
|
/// <returns>`true`, если значение совместимо с текущим типом.</returns>
|
||||||
public override bool IsCompatibleValue(JToken value)
|
public override bool IsCompatibleValue(JToken value)
|
||||||
{
|
{
|
||||||
return Resolver.TokenType(value) == JTokenType.Array;
|
return Resolver.TokenType(value) == JTokenType.Array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Добавление нового значения.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Новое значение.</param>
|
||||||
public override void AddValue(JToken value)
|
public override void AddValue(JToken value)
|
||||||
{
|
{
|
||||||
if (value.Type != JTokenType.Array)
|
if (value.Type != JTokenType.Array)
|
||||||
@@ -41,16 +55,27 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Подготовка типа к красивому представлению.
|
||||||
|
/// </summary>
|
||||||
public override void Beautify()
|
public override void Beautify()
|
||||||
{
|
{
|
||||||
|
ElementSchema.Beautify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение строкового представоения типа элемента.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Строковое представоение типа элемента</returns>
|
||||||
public override string GetTypeName()
|
public override string GetTypeName()
|
||||||
{
|
{
|
||||||
return $"array<{ElementSchema.GetTypeName()}>";
|
return $"array<{ElementSchema.GetTypeName()}>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Полное строковое представление элемента.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Строковое представление элемента.</returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return string.Join("\n" + Tab, [
|
return string.Join("\n" + Tab, [
|
||||||
|
|||||||
@@ -1,23 +1,37 @@
|
|||||||
using System;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.SchemaBuilder.Types
|
namespace Pf2eDataScrapper.SchemaBuilder.Types
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Тип представоления словаря в схеме.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent">Элемент, к которому добавляется тип.</param>
|
||||||
internal class DictionarySchemaType(SchemaNode parent) : AbstractSchemaType(parent)
|
internal class DictionarySchemaType(SchemaNode parent) : AbstractSchemaType(parent)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Схема ключей словаря.
|
||||||
|
/// </summary>
|
||||||
public SchemaNode KeyNode = new(parent, "[key]");
|
public SchemaNode KeyNode = new(parent, "[key]");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Схема значений словаря.
|
||||||
|
/// </summary>
|
||||||
public SchemaNode ItemNode = new(parent, "[value]");
|
public SchemaNode ItemNode = new(parent, "[value]");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проверка, что значение совместимо с текущим типом.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Проверяемое значение.</param>
|
||||||
|
/// <returns>`true`, если значение совместимо с текущим типом.</returns>
|
||||||
public override bool IsCompatibleValue(JToken value)
|
public override bool IsCompatibleValue(JToken value)
|
||||||
{
|
{
|
||||||
return Resolver.TokenType(value) == JTokenType.Object;
|
return Resolver.TokenType(value) == JTokenType.Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Добавление нового значения.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Новое значение.</param>
|
||||||
public override void AddValue(JToken value)
|
public override void AddValue(JToken value)
|
||||||
{
|
{
|
||||||
var obj = (JObject)value;
|
var obj = (JObject)value;
|
||||||
@@ -29,16 +43,28 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Подготовка типа к красивому представлению.
|
||||||
|
/// </summary>
|
||||||
public override void Beautify()
|
public override void Beautify()
|
||||||
{
|
{
|
||||||
|
KeyNode.Beautify();
|
||||||
|
ItemNode.Beautify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение строкового представоения типа элемента.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Строковое представоение типа элемента</returns>
|
||||||
public override string GetTypeName()
|
public override string GetTypeName()
|
||||||
{
|
{
|
||||||
return $"dict<{KeyNode.GetTypeName()}, {ItemNode.GetTypeName()}>";
|
return $"dict<{KeyNode.GetTypeName()}, {ItemNode.GetTypeName()}>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Полное строковое представление элемента.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Строковое представление элемента.</returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return string.Join("\n" + Tab, [
|
return string.Join("\n" + Tab, [
|
||||||
|
|||||||
@@ -1,24 +1,42 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.SchemaBuilder.Types
|
namespace Pf2eDataScrapper.SchemaBuilder.Types
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Тип, указывающий, что данные игнорируются.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent">Элемент, к которому добавляется тип.</param>
|
||||||
internal class IgnoreSchemaType(SchemaNode parent) : AbstractSchemaType(parent)
|
internal class IgnoreSchemaType(SchemaNode parent) : AbstractSchemaType(parent)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Проверка, что значение совместимо с текущим типом.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Проверяемое значение.</param>
|
||||||
|
/// <returns>`true`, если значение совместимо с текущим типом.</returns>
|
||||||
public override bool IsCompatibleValue(JToken value)
|
public override bool IsCompatibleValue(JToken value)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Добавление нового значения.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Новое значение.</param>
|
||||||
public override void AddValue(JToken value)
|
public override void AddValue(JToken value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Подготовка типа к красивому представлению.
|
||||||
|
/// </summary>
|
||||||
public override void Beautify()
|
public override void Beautify()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение строкового представоения типа элемента.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Строковое представоение типа элемента</returns>
|
||||||
public override string GetTypeName()
|
public override string GetTypeName()
|
||||||
{
|
{
|
||||||
return "ignore";
|
return "ignore";
|
||||||
|
|||||||
@@ -1,21 +1,32 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Pf2eDataScrapper.SchemaBuilder.Types
|
namespace Pf2eDataScrapper.SchemaBuilder.Types
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Тип представоления объектов в схеме.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent">Элемент, к которому добавляется тип.</param>
|
||||||
internal class ObjectSchemaType(SchemaNode parent) : AbstractSchemaType(parent)
|
internal class ObjectSchemaType(SchemaNode parent) : AbstractSchemaType(parent)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Элемнты полей объекта.
|
||||||
|
/// </summary>
|
||||||
public List<SchemaNode> Fields = [];
|
public List<SchemaNode> Fields = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проверка, что значение совместимо с текущим типом.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Проверяемое значение.</param>
|
||||||
|
/// <returns>`true`, если значение совместимо с текущим типом.</returns>
|
||||||
public override bool IsCompatibleValue(JToken value)
|
public override bool IsCompatibleValue(JToken value)
|
||||||
{
|
{
|
||||||
return Resolver.TokenType(value) == JTokenType.Object;
|
return Resolver.TokenType(value) == JTokenType.Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Добавление нового значения.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Новое значение.</param>
|
||||||
public override void AddValue(JToken value)
|
public override void AddValue(JToken value)
|
||||||
{
|
{
|
||||||
var obj = (JObject)value;
|
var obj = (JObject)value;
|
||||||
@@ -42,6 +53,9 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Подготовка типа к красивому представлению.
|
||||||
|
/// </summary>
|
||||||
public override void Beautify()
|
public override void Beautify()
|
||||||
{
|
{
|
||||||
Fields.Sort((a, b) =>
|
Fields.Sort((a, b) =>
|
||||||
@@ -51,7 +65,7 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.Name.CompareTo(b.Name);
|
return string.Compare(a.Name, b.Name, StringComparison.Ordinal);
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (var field in Fields)
|
foreach (var field in Fields)
|
||||||
@@ -60,11 +74,19 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение строкового представоения типа элемента.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Строковое представоение типа элемента</returns>
|
||||||
public override string GetTypeName()
|
public override string GetTypeName()
|
||||||
{
|
{
|
||||||
return "object";
|
return "object";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Полное строковое представление элемента.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Строковое представление элемента.</returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
List<string> rows = [base.ToString()];
|
List<string> rows = [base.ToString()];
|
||||||
|
|||||||
@@ -2,17 +2,37 @@
|
|||||||
|
|
||||||
namespace Pf2eDataScrapper.SchemaBuilder.Types
|
namespace Pf2eDataScrapper.SchemaBuilder.Types
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Тип представоления простых значений в схеме.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent">Элемент, к которому добавляется тип.</param>
|
||||||
|
/// <param name="type">Тип значения.</param>
|
||||||
internal class StaticSchemaType(SchemaNode parent, JTokenType type) : AbstractSchemaType(parent)
|
internal class StaticSchemaType(SchemaNode parent, JTokenType type) : AbstractSchemaType(parent)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Тип значения.
|
||||||
|
/// </summary>
|
||||||
protected JTokenType Type = type;
|
protected JTokenType Type = type;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Набор возможных значений и их количества.
|
||||||
|
/// </summary>
|
||||||
protected Dictionary<JToken, int> Values = [];
|
protected Dictionary<JToken, int> Values = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проверка, что значение совместимо с текущим типом.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Проверяемое значение.</param>
|
||||||
|
/// <returns>`true`, если значение совместимо с текущим типом.</returns>
|
||||||
public override bool IsCompatibleValue(JToken value)
|
public override bool IsCompatibleValue(JToken value)
|
||||||
{
|
{
|
||||||
return value.Type == Type;
|
return value.Type == Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Добавление нового значения.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Новое значение.</param>
|
||||||
public override void AddValue(JToken value)
|
public override void AddValue(JToken value)
|
||||||
{
|
{
|
||||||
Values.TryAdd(value, 0);
|
Values.TryAdd(value, 0);
|
||||||
@@ -20,6 +40,9 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types
|
|||||||
Values[value]++;
|
Values[value]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Подготовка типа к красивому представлению.
|
||||||
|
/// </summary>
|
||||||
public override void Beautify()
|
public override void Beautify()
|
||||||
{
|
{
|
||||||
if (Type == JTokenType.String)
|
if (Type == JTokenType.String)
|
||||||
@@ -39,11 +62,19 @@ namespace Pf2eDataScrapper.SchemaBuilder.Types
|
|||||||
Values = Values.OrderByDescending(pair => pair.Value).ToDictionary(pair => pair.Key, pair => pair.Value);
|
Values = Values.OrderByDescending(pair => pair.Value).ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение строкового представоения типа элемента.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Строковое представоение типа элемента</returns>
|
||||||
public override string GetTypeName()
|
public override string GetTypeName()
|
||||||
{
|
{
|
||||||
return Type.ToString().ToLower();
|
return Type.ToString().ToLower();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Полное строковое представление элемента.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Строковое представление элемента.</returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
var result = base.ToString();
|
var result = base.ToString();
|
||||||
|
|||||||
Reference in New Issue
Block a user