Compare commits

...
2 Commits
Author SHA1 Message Date
kozhilya 2ed5c2e5c5 Немного правок на ночь 2025-04-17 00:46:44 +04:00
kozhilya 0353ca732f Обновление README.md 2025-04-17 00:08:42 +04:00
9 changed files with 2168 additions and 67 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
# Путь к папка для распаковки репозиториев обрабатываемых данных # Путь к папке для распаковки репозиториев обрабатываемых данных
DATA_DIR=D:\path\to\directory\with\repositories DATA_DIR=D:\path\to\directory\with\repositories
# Путь к месту сохранения схем # Путь к месту сохранения схем
@@ -86,7 +86,7 @@ internal abstract class AbstractProcessor(JObject input)
throw new Exception("system.traits.value is expected to be an array"); throw new Exception("system.traits.value is expected to be an array");
} }
foreach(var trait in GetTraits(traitsJson.ToArray().Select(jToken => jToken.ToString()))) foreach(Trait trait in GetTraits(traitsJson.ToArray().Select(jToken => jToken.ToString())))
{ {
Entity.Traits.Add(trait); Entity.Traits.Add(trait);
} }
@@ -122,17 +122,12 @@ internal abstract class AbstractProcessor(JObject input)
{ {
string? value = GetOptional<string>(path); string? value = GetOptional<string>(path);
if (value is null) return value is null ? defaultValue : DataBuilderHelper.Enum<T>(value);
{
return defaultValue;
}
return DataBuilderHelper.Enum<T>(value);
} }
protected Source GetSource(string name) protected Source GetSource(string name)
{ {
Source? source = Context.Sources.Where(s => s.Name == name).FirstOrDefault(); Source? source = Context.Sources.FirstOrDefault(s => s.Name == name);
if (source != null) if (source != null)
{ {
@@ -151,9 +146,9 @@ internal abstract class AbstractProcessor(JObject input)
protected ExternalTarget GetTarget() protected ExternalTarget GetTarget()
{ {
string name = "pf2e - Foundry module"; const string name = "pf2e - Foundry module";
ExternalTarget? target = Context.ExternalTargets.Where(s => s.Name == name).FirstOrDefault(); ExternalTarget? target = Context.ExternalTargets.FirstOrDefault(s => s.Name == name);
if (target != null) if (target != null)
{ {
@@ -173,9 +168,9 @@ internal abstract class AbstractProcessor(JObject input)
protected IEnumerable<Trait> GetTraits(IEnumerable<string> names) protected IEnumerable<Trait> GetTraits(IEnumerable<string> names)
{ {
var result = Context.Traits.Where(t => names.Contains(t.Name)).ToList(); List<Trait> result = Context.Traits.Where(t => names.Contains(t.Name)).ToList();
foreach (var name in names) foreach (string name in names)
{ {
if (result.Any(t => t.Name == name)) if (result.Any(t => t.Name == name))
{ {
@@ -198,9 +193,9 @@ internal abstract class AbstractProcessor(JObject input)
public static string Md5(string input, bool isLowercase = false) public static string Md5(string input, bool isLowercase = false)
{ {
using var md5 = MD5.Create(); using MD5 md5 = MD5.Create();
var byteHash = md5.ComputeHash(Encoding.UTF8.GetBytes(input)); byte[] byteHash = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
var hash = BitConverter.ToString(byteHash).Replace("-", ""); string hash = BitConverter.ToString(byteHash).Replace("-", "");
return (isLowercase) ? hash.ToLower() : hash; return (isLowercase) ? hash.ToLower() : hash;
} }
} }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Pf2eDataScrapper.Migrations
{
/// <inheritdoc />
public partial class Typo : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}
@@ -387,6 +387,47 @@ namespace Pf2eDataScrapper.Migrations
b.ToTable("external_targets", (string)null); b.ToTable("external_targets", (string)null);
}); });
modelBuilder.Entity("Pf2eDataScrapper.Model.Base.Trait", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id")
.HasColumnOrder(1);
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text")
.HasColumnName("description")
.HasColumnOrder(5);
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("name")
.HasColumnOrder(2);
b.Property<string>("Slug")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("slug")
.HasColumnOrder(4);
b.Property<TraitType>("Type")
.HasColumnType("trait_type")
.HasColumnName("type")
.HasColumnOrder(3);
b.HasKey("Id")
.HasName("pk_traits");
b.ToTable("traits", (string)null);
});
modelBuilder.Entity("Pf2eDataScrapper.Model.Common.Frequency", b => modelBuilder.Entity("Pf2eDataScrapper.Model.Common.Frequency", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@@ -476,47 +517,6 @@ namespace Pf2eDataScrapper.Migrations
b.ToTable("trainings", (string)null); b.ToTable("trainings", (string)null);
}); });
modelBuilder.Entity("Pf2eDataScrapper.Model.Common.Trait", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id")
.HasColumnOrder(1);
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text")
.HasColumnName("description")
.HasColumnOrder(5);
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("name")
.HasColumnOrder(2);
b.Property<string>("Slug")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("slug")
.HasColumnOrder(4);
b.Property<TraitType>("Type")
.HasColumnType("trait_type")
.HasColumnName("type")
.HasColumnOrder(3);
b.HasKey("Id")
.HasName("pk_traits");
b.ToTable("traits", (string)null);
});
modelBuilder.Entity("Pf2eDataScrapper.Model.Structure.Action", b => modelBuilder.Entity("Pf2eDataScrapper.Model.Structure.Action", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@@ -1498,7 +1498,7 @@ namespace Pf2eDataScrapper.Migrations
.IsRequired() .IsRequired()
.HasConstraintName("fk_entity_trait_entities_entities_id"); .HasConstraintName("fk_entity_trait_entities_entities_id");
b.HasOne("Pf2eDataScrapper.Model.Common.Trait", null) b.HasOne("Pf2eDataScrapper.Model.Base.Trait", null)
.WithMany() .WithMany()
.HasForeignKey("TraitsId") .HasForeignKey("TraitsId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
@@ -1554,7 +1554,7 @@ namespace Pf2eDataScrapper.Migrations
modelBuilder.Entity("Pf2eDataScrapper.Model.Base.Targets.EntityExternal", b => modelBuilder.Entity("Pf2eDataScrapper.Model.Base.Targets.EntityExternal", b =>
{ {
b.HasOne("Pf2eDataScrapper.Model.Base.Entity", "Entity") b.HasOne("Pf2eDataScrapper.Model.Base.Entity", "Entity")
.WithMany("Extrnals") .WithMany("Externals")
.HasForeignKey("EntityId") .HasForeignKey("EntityId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired() .IsRequired()
@@ -1967,7 +1967,7 @@ namespace Pf2eDataScrapper.Migrations
{ {
b.Navigation("Aliases"); b.Navigation("Aliases");
b.Navigation("Extrnals"); b.Navigation("Externals");
b.Navigation("Sources"); b.Navigation("Sources");
}); });
+1 -2
View File
@@ -2,7 +2,6 @@
using Pf2eDataScrapper.Model.Base.Keywords; using Pf2eDataScrapper.Model.Base.Keywords;
using Pf2eDataScrapper.Model.Base.Source; using Pf2eDataScrapper.Model.Base.Source;
using Pf2eDataScrapper.Model.Base.Targets; using Pf2eDataScrapper.Model.Base.Targets;
using Pf2eDataScrapper.Model.Common;
using Pf2eDataScrapper.Model.Enum; using Pf2eDataScrapper.Model.Enum;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
@@ -57,5 +56,5 @@ public class Entity
public virtual ICollection<EntitySource> Sources { get; set; } = []; public virtual ICollection<EntitySource> Sources { get; set; } = [];
public virtual ICollection<EntityExternal> Extrnals { get; set; } = []; public virtual ICollection<EntityExternal> Externals { get; set; } = [];
} }
@@ -1,13 +1,12 @@
using Pf2eDataScrapper.Model.Base; using Pf2eDataScrapper.Model.Enum;
using Pf2eDataScrapper.Model.Enum;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
namespace Pf2eDataScrapper.Model.Common; namespace Pf2eDataScrapper.Model.Base;
public partial class Trait public partial class Trait
{ {
[System.ComponentModel.DataAnnotations.Key] [Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column(Order = 1)] [Column(Order = 1)]
public int Id { get; set; } public int Id { get; set; }
+1 -1
View File
@@ -77,7 +77,7 @@ public partial class Pf2eDbContext
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
// EntityExternal // EntityExternal
entity.HasMany(e => e.Extrnals).WithOne(e => e.Entity) entity.HasMany(e => e.Externals).WithOne(e => e.Entity)
.HasForeignKey(e => e.EntityId) .HasForeignKey(e => e.EntityId)
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
}); });
+35
View File
@@ -2,6 +2,17 @@
Программа обработки данных для игры Pathfinder 2e для создания БД для дальнейшего использования на сайте локализации Pf2e. Программа обработки данных для игры Pathfinder 2e для создания БД для дальнейшего использования на сайте локализации Pf2e.
## Начало работы
- Склонируйте репозиторий и войдите в папку `Pf2eDataScrapper`.
- Создайте файл `.env` и добавьте в него содержимое из файла `.env.example`. Измените содержащиеся поля:
- `DATA_DIR` - путь к папке для распаковки репозиториев обрабатываемых данных;
- `OUTPUT_DIR` - путь к месту сохранения схем;
- `DATABASE_CONNECTION` - строка подключения к БД (только PostreSQL).
- Для создания структуры БД в командной строке запустите `dotnet ef database update`.
- Проект готов к работе.
## Общая структура ## Общая структура
### `SchemaBuilder` ### `SchemaBuilder`
@@ -17,6 +28,30 @@ data = JObject.Parse(reader.ReadToEnd()); // Загрузка данных
schema.AddValue(data); // Добавление данных schema.AddValue(data); // Добавление данных
``` ```
### `Model`
Набор классов модели ORM EntityFramework.
Класс-контекст `Pf2eDbContext` разделён на 2 файла:
- в `Pf2eDbContext.cs` находится набор таблиц и конфигурация БД,
- в `Pf2eDbContextModel.cs` находится Fluent API описание связей в модели.
Для удобства модель разбита на несколько папок-пространст имён:
- `Base` - здесь описан класс `Entity`, который является корнем всех связей и описаний. В этой таблице находятся общие характеристики объектов: название, описание, тип, а так же ссылки на общие элементы: указание источников и трейтов - всё это в пространстве имён
- `Common` содержит общее классы на которые могут ссылаться разные типа.
- `Enum` содержит описание всех перечислений, использующихся в модели.
- `Structure` содержит все основные типы, которые связаны 1-к-1 с `Entity` (для указания этого используется интерфейс `IEntity`).
### `Migrations`
Миграции БД, генерируются в автомотическом режиме.
### `Importers` ### `Importers`
Классы загрузки и обработки данных. Классы загрузки и обработки данных.
# TODO
- Добавление экипировки
- Добавление бестиария