From bf6d600c4bb9959c26b5e6e595bb27d264d7cdc5 Mon Sep 17 00:00:00 2001 From: kozhilya Date: Tue, 15 Apr 2025 19:16:10 +0400 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=B8=D1=81=D1=82=D0=BE=D1=87=D0=BD=D0=B8=D0=BA?= =?UTF-8?q?=D0=B0=20Foundry,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B0=D0=BB=D0=B8=D0=B0=D1=81=D0=B0,=20?= =?UTF-8?q?=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B0=20Action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Compendium/CompendiumFolderCollection.cs | 3 +- .../DataBuilder/AbstractProcessor.cs | 54 +++++++++++- .../DataBuilder/Processors/ActionProcessor.cs | 32 +++++++ .../Processors/ConditionProcessor.cs | 5 +- Pf2eDataScrapper/Model/Action.cs | 18 ---- .../Model/{ => Common}/EntitySource.cs | 4 +- Pf2eDataScrapper/Model/{ => Common}/Source.cs | 2 +- Pf2eDataScrapper/Model/Structure/Action.cs | 25 ++++++ .../Model/{ => Structure}/Condition.cs | 9 +- Pf2eDataScrapper/Model/Training.cs | 4 +- .../{Pf2eTestContext.cs => Pf2eDbContext.cs} | 84 +++++++++++-------- Pf2eDataScrapper/Program.cs | 10 ++- 12 files changed, 181 insertions(+), 69 deletions(-) create mode 100644 Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Processors/ActionProcessor.cs delete mode 100644 Pf2eDataScrapper/Model/Action.cs rename Pf2eDataScrapper/Model/{ => Common}/EntitySource.cs (81%) rename Pf2eDataScrapper/Model/{ => Common}/Source.cs (78%) create mode 100644 Pf2eDataScrapper/Model/Structure/Action.cs rename Pf2eDataScrapper/Model/{ => Structure}/Condition.cs (52%) rename Pf2eDataScrapper/{Pf2eTestContext.cs => Pf2eDbContext.cs} (92%) diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolderCollection.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolderCollection.cs index 532c5e3..38df888 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolderCollection.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/Compendium/CompendiumFolderCollection.cs @@ -21,7 +21,6 @@ internal class CompendiumFolderCollection : List /// public CompendiumFolderCollection Filter() { - // return [.. this.FindAll(x => x.Type != CompendiumDocumentType.Actor)]; - return [.. this.FindAll(x => x.Type != CompendiumDocumentType.Actor && x.Name == "Conditions")]; + return [.. this.FindAll(x => x.Type != CompendiumDocumentType.Actor)]; } } diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/AbstractProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/AbstractProcessor.cs index a53a4d0..cb80515 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/AbstractProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/AbstractProcessor.cs @@ -8,7 +8,7 @@ namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder; internal abstract class AbstractProcessor(JObject input) { - public readonly Pf2eTestContext Context = new(); + public readonly Pf2eDbContext Context = new(); public readonly JObject Input = input; @@ -38,6 +38,34 @@ internal abstract class AbstractProcessor(JObject input) Context.Entities.Add(Entity); + // Alias + EntityAlias alias = new() + { + Type = AliasType.English, + Alias = Entity.Name, + EntityId = Entity.Id, + Entity = Entity + }; + Context.EntityAliases.Add(alias); + + // Source + EntitySource source = new() + { + EntityId = Entity.Id, + Entity = Entity, + + Source = GetSource(), + + Suffix = GetRequired("_id"), + IsRemaster = GetRequired("system.publication.remaster") + }; + Context.EntitySources.Add(source); + + // Traits + JToken? traits = Input.SelectToken("system.traits"); + + Console.WriteLine($"{Entity.Name} - Traits: {traits}"); + // TODO Traits, Alias } @@ -57,7 +85,7 @@ internal abstract class AbstractProcessor(JObject input) { JToken? token = Input.SelectToken(path) ?? null; - return token is null ? default! : token.ToObject() ?? default; + return (token is null || token.Type == JTokenType.Null) ? default! : token.ToObject() ?? default; } public T EnumRequired(string path) where T : Enum @@ -94,4 +122,26 @@ internal abstract class AbstractProcessor(JObject input) return default; } + + + protected Source GetSource() + { + string name = "pf2e - Foundry module"; + + Source? source = Context.Sources.Where(s => s.Name == name).FirstOrDefault(); + + if (source != null) + { + return source; + } + + source = new() + { + Name = "pf2e - Foundry module", + Url = "https://github.com/foundryvtt/pf2e" + }; + + Context.Sources.Add(source); + return source; + } } diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Processors/ActionProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Processors/ActionProcessor.cs new file mode 100644 index 0000000..b0bcc10 --- /dev/null +++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Processors/ActionProcessor.cs @@ -0,0 +1,32 @@ +using Newtonsoft.Json.Linq; +using Pf2eDataScrapper.Model.Enum; + +namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder.Processors; + +[Pf2eTypeProcessor("Item.action")] +internal class ActionProcessor(JObject input) : AbstractProcessor(input) +{ + public override EntityType Type => EntityType.Action; + + public override Model.Structure.Action Object { get; } = new(); + + public override void Process() + { + base.Process(); + + + Object.Type = EnumRequired("system.actionType.value"); + Object.Category = EnumRequired("system.category"); + Object.Actions = GetOptional("system.actions.value"); + Object.DeathNote = GetOptional("system.deathNote"); + + JObject extra = new() + { + { "selfEffect", Input.SelectToken("system.selfEffect") } + }; + + Object.Extra = extra.ToString(Newtonsoft.Json.Formatting.None); + + Context.Actions.Add(Object); + } +} diff --git a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Processors/ConditionProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Processors/ConditionProcessor.cs index 7964365..3f01d18 100644 --- a/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Processors/ConditionProcessor.cs +++ b/Pf2eDataScrapper/Importers/Implementations/Pf2eFoundry/DataBuilder/Processors/ConditionProcessor.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json.Linq; -using Pf2eDataScrapper.Model; using Pf2eDataScrapper.Model.Enum; +using Pf2eDataScrapper.Model.Structure; namespace Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry.DataBuilder.Processors; @@ -23,8 +23,7 @@ internal class ConditionProcessor(JObject input) : AbstractProcessor(input) { "value", Input.SelectToken("system.value") } }; - Object.Extra = extra.ToString(Newtonsoft.Json.Formatting.Indented); - + Object.Extra = extra.ToString(Newtonsoft.Json.Formatting.None); Object.Group = EnumOptional("system.group"); Context.Conditions.Add(Object); diff --git a/Pf2eDataScrapper/Model/Action.cs b/Pf2eDataScrapper/Model/Action.cs deleted file mode 100644 index 1d4b0ae..0000000 --- a/Pf2eDataScrapper/Model/Action.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Pf2eDataScrapper.Model.Common; - -namespace Pf2eDataScrapper.Model; - -public partial class Action : IEntity -{ - public int Id { get; set; } - - public Entity Entity { get; set; } = null!; - - // TODO ActionType - - public int? Actions { get; set; } - - public bool? DeathNote { get; set; } - - public string? Extra { get; set; } -} diff --git a/Pf2eDataScrapper/Model/EntitySource.cs b/Pf2eDataScrapper/Model/Common/EntitySource.cs similarity index 81% rename from Pf2eDataScrapper/Model/EntitySource.cs rename to Pf2eDataScrapper/Model/Common/EntitySource.cs index eee0535..3978de3 100644 --- a/Pf2eDataScrapper/Model/EntitySource.cs +++ b/Pf2eDataScrapper/Model/Common/EntitySource.cs @@ -1,6 +1,4 @@ -using Pf2eDataScrapper.Model.Common; - -namespace Pf2eDataScrapper.Model; +namespace Pf2eDataScrapper.Model.Common; public partial class EntitySource { diff --git a/Pf2eDataScrapper/Model/Source.cs b/Pf2eDataScrapper/Model/Common/Source.cs similarity index 78% rename from Pf2eDataScrapper/Model/Source.cs rename to Pf2eDataScrapper/Model/Common/Source.cs index 46d4990..35ef945 100644 --- a/Pf2eDataScrapper/Model/Source.cs +++ b/Pf2eDataScrapper/Model/Common/Source.cs @@ -1,4 +1,4 @@ -namespace Pf2eDataScrapper.Model; +namespace Pf2eDataScrapper.Model.Common; public partial class Source { diff --git a/Pf2eDataScrapper/Model/Structure/Action.cs b/Pf2eDataScrapper/Model/Structure/Action.cs new file mode 100644 index 0000000..1f53780 --- /dev/null +++ b/Pf2eDataScrapper/Model/Structure/Action.cs @@ -0,0 +1,25 @@ +using Pf2eDataScrapper.Model.Common; +using Pf2eDataScrapper.Model.Enum; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Pf2eDataScrapper.Model.Structure; + +public partial class Action : IEntity +{ + [Key] + [Column("id", Order = 1)] + public int Id { get; set; } + + public Entity Entity { get; set; } = null!; + + public ActionType Type { get; set; } + + public ActionCategory Category { get; set; } + + public int? Actions { get; set; } + + public bool? DeathNote { get; set; } + + public string? Extra { get; set; } +} diff --git a/Pf2eDataScrapper/Model/Condition.cs b/Pf2eDataScrapper/Model/Structure/Condition.cs similarity index 52% rename from Pf2eDataScrapper/Model/Condition.cs rename to Pf2eDataScrapper/Model/Structure/Condition.cs index 36df080..025b152 100644 --- a/Pf2eDataScrapper/Model/Condition.cs +++ b/Pf2eDataScrapper/Model/Structure/Condition.cs @@ -1,15 +1,22 @@ using Pf2eDataScrapper.Model.Common; using Pf2eDataScrapper.Model.Enum; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; -namespace Pf2eDataScrapper.Model; +namespace Pf2eDataScrapper.Model.Structure; +[Table("condition")] public partial class Condition : IEntity { + [Key] + [Column("id", Order = 1)] public int Id { get; set; } public Entity Entity { get; set; } = null!; + [Column("group", Order = 2)] public ConditionGroup? Group { get; set; } + [Column("extra", Order = 3)] public string? Extra { get; set; } } diff --git a/Pf2eDataScrapper/Model/Training.cs b/Pf2eDataScrapper/Model/Training.cs index a528995..223b75f 100644 --- a/Pf2eDataScrapper/Model/Training.cs +++ b/Pf2eDataScrapper/Model/Training.cs @@ -6,7 +6,7 @@ public partial class Training public string Key { get; set; } = null!; - public virtual ICollection ClassTrainings { get; set; } = new List(); + public virtual ICollection ClassTrainings { get; set; } = []; - public virtual ICollection Deities { get; set; } = new List(); + public virtual ICollection Deities { get; set; } = []; } diff --git a/Pf2eDataScrapper/Pf2eTestContext.cs b/Pf2eDataScrapper/Pf2eDbContext.cs similarity index 92% rename from Pf2eDataScrapper/Pf2eTestContext.cs rename to Pf2eDataScrapper/Pf2eDbContext.cs index b66930e..cd7ae43 100644 --- a/Pf2eDataScrapper/Pf2eTestContext.cs +++ b/Pf2eDataScrapper/Pf2eDbContext.cs @@ -2,23 +2,24 @@ using Pf2eDataScrapper.Model; using Pf2eDataScrapper.Model.Common; using Pf2eDataScrapper.Model.Enum; +using Pf2eDataScrapper.Model.Structure; namespace Pf2eDataScrapper; -public partial class Pf2eTestContext : DbContext +public partial class Pf2eDbContext : DbContext { - public Pf2eTestContext() + public Pf2eDbContext() { } - public Pf2eTestContext(DbContextOptions options) + public Pf2eDbContext(DbContextOptions options) : base(options) { } #region DbSets - public virtual DbSet Actions { get; set; } + public virtual DbSet Actions { get; set; } public virtual DbSet Ancestries { get; set; } @@ -110,7 +111,25 @@ public partial class Pf2eTestContext : DbContext { builder .MapEnum("entity_type") - .MapEnum("condition_group"); + .MapEnum("entity_rarity") + .MapEnum("alias_type") + .MapEnum("trait_type") + .MapEnum("action_type") + .MapEnum("action_category") + .MapEnum("enum_size") + .MapEnum("ancestry_vision") + .MapEnum("campaign_feature_category") + .MapEnum("class_progression_type") + .MapEnum("condition_group") + .MapEnum("deity_category") + .MapEnum("deity_fonts") + .MapEnum("deity_sanctification") + .MapEnum("feat_action_type") + .MapEnum("feat_category") + .MapEnum("spell_area_type") + .MapEnum("spell_damage_category") + .MapEnum("spell_damage_kinds") + ; } ); } @@ -121,30 +140,26 @@ public partial class Pf2eTestContext : DbContext modelBuilder .HasPostgresEnum("entity_type") + .HasPostgresEnum("entity_rarity") + .HasPostgresEnum("alias_type") + .HasPostgresEnum("trait_type") + .HasPostgresEnum("action_type") + .HasPostgresEnum("action_category") + .HasPostgresEnum("enum_size") + .HasPostgresEnum("ancestry_vision") + .HasPostgresEnum("campaign_feature_category") + .HasPostgresEnum("class_progression_type") .HasPostgresEnum("condition_group") + .HasPostgresEnum("deity_category") + .HasPostgresEnum("deity_fonts") + .HasPostgresEnum("deity_sanctification") + .HasPostgresEnum("feat_action_type") + .HasPostgresEnum("feat_category") + .HasPostgresEnum("spell_area_type") + .HasPostgresEnum("spell_damage_category") + .HasPostgresEnum("spell_damage_kinds") ; - modelBuilder - .HasPostgresEnum("action_category", new[] { "offensive", "defensive", "interaction", "familiar" }) - .HasPostgresEnum("action_type", new[] { "action", "free", "reaction", "passive" }) - .HasPostgresEnum("alias_type", new[] { "old", "english", "hobby" }) - .HasPostgresEnum("ancestry_vision", new[] { "normal", "low_light_vision", "darkvision" }) - .HasPostgresEnum("campaign_feature_category", new[] { "army_tactic", "army_war_action", "kingdom_activity", "kingdom_feat", "kingdom_feature" }) - .HasPostgresEnum("class_progression_type", new[] { "entity", "ancestry_feat", "class_feat", "general_feat", "skill_feat", "skill_increase" }) - // .HasPostgresEnum("condition_group", new[] { "senses", "abilities", "death", "attitudes", "detection" }) - .HasPostgresEnum("deity_category", new[] { "deity", "pantheon", "covenant", "philosophy" }) - .HasPostgresEnum("deity_fonts", new[] { "none", "heal", "harm", "any" }) - .HasPostgresEnum("deity_sanctification", new[] { "holy", "unholy", "any" }) - .HasPostgresEnum("entity_rarity", new[] { "common", "uncommon", "rare", "unique" }) - // .HasPostgresEnum("entity_type", new[] { "action", "ancestry", "background", "backpack", "campaign_feature", "class", "condition", "deity", "feat", "heritage", "spell" }) - .HasPostgresEnum("enum_size", new[] { "med", "lanuages", "system", "tiny" }) - .HasPostgresEnum("feat_category", new[] { "ancestryfeature", "classfeature", "calling", "class", "skill", "general", "ancestry", "bonus", "deityboon", "curse", "pfsboon" }) - .HasPostgresEnum("spell_area_type", new[] { "burst", "emanation", "cone", "line", "square", "cube", "cylinder" }) - .HasPostgresEnum("spell_damage_category", new[] { "persistent", "splash" }) - .HasPostgresEnum("spell_damage_kinds", new[] { "damage", "healing", "any" }) - .HasPostgresEnum("trait_type", new[] { "regular", "tradition" }); - - modelBuilder.Entity(entity => { entity.HasKey(e => e.Id).HasName("entity_pkey"); @@ -153,7 +168,6 @@ public partial class Pf2eTestContext : DbContext entity.Property(e => e.Id).HasColumnName("id"); entity.Property(e => e.Description).HasColumnName("description"); - entity.Property(e => e.DescriptionGm).HasColumnName("description_gm"); entity.Property(e => e.Type).HasColumnName("type"); entity.Property(e => e.Img) .HasMaxLength(150) @@ -171,7 +185,7 @@ public partial class Pf2eTestContext : DbContext .HasMaxLength(150) .HasColumnName("slug"); - entity.HasMany(d => d.Traits).WithMany() + entity.HasMany(d => d.Traits).WithMany(t => t.Entities) .UsingEntity>( "EntityTrait", r => r.HasOne().WithMany() @@ -261,9 +275,9 @@ public partial class Pf2eTestContext : DbContext modelBuilder.Entity(entity => { - entity - .HasNoKey() - .ToTable("entity_sources"); + entity.HasKey(p => new { p.EntityId, p.SourceId }).HasName("entity_sources_pkey"); + + entity.ToTable("entity_sources"); entity.Property(e => e.EntityId).HasColumnName("entity_id"); entity.Property(e => e.IsRemaster).HasColumnName("is_remaster"); @@ -407,7 +421,7 @@ public partial class Pf2eTestContext : DbContext - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasKey(e => e.Id).HasName("action_pkey"); @@ -417,11 +431,15 @@ public partial class Pf2eTestContext : DbContext .ValueGeneratedNever() .HasColumnName("id"); entity.HasOne(e => e.Entity).WithOne() - .HasForeignKey(e => e.Id) + .HasForeignKey(e => e.Id) .OnDelete(DeleteBehavior.ClientSetNull) .HasConstraintName("action_id_fkey"); entity.Property(e => e.Actions).HasColumnName("actions"); entity.Property(e => e.DeathNote).HasColumnName("death_note"); + + entity.Property(e => e.Type).HasColumnName("action_type"); + entity.Property(e => e.Category).HasColumnName("category"); + entity.Property(e => e.Extra).HasColumnName("extra"); }); diff --git a/Pf2eDataScrapper/Program.cs b/Pf2eDataScrapper/Program.cs index 57a9bb7..8fdeff4 100644 --- a/Pf2eDataScrapper/Program.cs +++ b/Pf2eDataScrapper/Program.cs @@ -1,14 +1,16 @@ using Pf2eDataScrapper; using Pf2eDataScrapper.Importers.Implementations.Aonprd; +using Pf2eDataScrapper.Importers.Implementations.Pf2eFoundry; EnvSettings.Load(); -AonprdImporter importer = new AonprdImporter(); +/* +AonprdImporter importer = new(); importer.Prepare(); importer.BuildSchemas(); +*/ -/* -var importer = new Pf2EFoundryImporter(); + +Pf2EFoundryImporter importer = new(); importer.Prepare(); importer.Import(); -*/ \ No newline at end of file