Compare commits
2
Commits
bfe52cff9a
...
2ed5c2e5c5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ed5c2e5c5 | ||
|
|
0353ca732f |
@@ -1,4 +1,4 @@
|
|||||||
# Путь к папка для распаковки репозиториев обрабатываемых данных
|
# Путь к папке для распаковки репозиториев обрабатываемых данных
|
||||||
DATA_DIR=D:\path\to\directory\with\repositories
|
DATA_DIR=D:\path\to\directory\with\repositories
|
||||||
|
|
||||||
# Путь к месту сохранения схем
|
# Путь к месту сохранения схем
|
||||||
|
|||||||
+10
-15
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2051
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");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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; }
|
||||||
@@ -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);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
- Добавление экипировки
|
||||||
|
- Добавление бестиария
|
||||||
Reference in New Issue
Block a user