From ff715df3ccda51c1bb3d4b84f4391b4fdd1962dd Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Tue, 22 Aug 2023 10:00:21 +1000 Subject: Finalised initial implementation of NSFW tag filtering --- Services/TagService.cs | 79 +++++++++++++++++++++++++++++++++++++++----- Services/UserStateService.cs | 21 ++++++++++++ 2 files changed, 91 insertions(+), 9 deletions(-) create mode 100644 Services/UserStateService.cs (limited to 'Services') diff --git a/Services/TagService.cs b/Services/TagService.cs index 8de52ff..860103b 100644 --- a/Services/TagService.cs +++ b/Services/TagService.cs @@ -14,12 +14,18 @@ public interface ITagService { public void RemoveTag(HBObject obj, TagDefinition tagDef); public void SetImplicitTags(TagDefinition tagDef, TagDefinition[] implicitTagDefs); public void SetImplicitTags(Guid tagDef, Guid[] implicitTagDefs); + public void AddImplicitTag(Guid tagDef, Guid implicitTagDef); + public void AddImplicitTag(TagDefinition tagDef, TagDefinition implicitTagDef); + public void RemoveImplicitTag(Guid tagDef, Guid implicitTagDef); + public void RemoveImplicitTag(TagDefinition tagDef, TagDefinition implicitTagDef); public void CreateTagDefinition(string name, string? @namespace); + public void DeleteTagDefinition(Guid tagDef); public void DeleteTagDefinition(TagDefinition tagDef); public void UpdateTagDefinition(Guid tagDef, string name, string? @namespace); public void UpdateTagDefinition(TagDefinition tagDef, string name, string? @namespace); public (TagDefinition tagDefinition, bool isImplicit)[] GetAllTags(Guid obj); public (TagDefinition tagDefinition, bool isImplicit)[] GetAllTags(HBObject obj); + public (TagDefinition tagDefinition, bool isImplicit)[] GetAllTags(TagDefinition tagDef); } public class TagService : ITagService { @@ -78,6 +84,31 @@ public class TagService : ITagService { public void SetImplicitTags(TagDefinition tagDef, TagDefinition[] implicitTagDefs) => SetImplicitTags(tagDef.Guid, implicitTagDefs.Select(td => td.Guid).ToArray()); + public void AddImplicitTag(Guid tagDef, Guid implicitTagDef) { + using var db = dbFactory.CreateDbContext(); + + var tag = db.TagDefinitions.First(td => td.Guid == tagDef); + var implicitTag = db.TagDefinitions.First(td => td.Guid == implicitTagDef); + + tag.ImplicitTags.Add(implicitTag); + db.SaveChanges(); + } + + public void AddImplicitTag(TagDefinition tagDef, TagDefinition implicitTagDef) => + AddImplicitTag(tagDef, implicitTagDef); + + public void RemoveImplicitTag(Guid tagDef, Guid implicitTagDef) { + using var db = dbFactory.CreateDbContext(); + + var tag = db.TagDefinitions.First(td => td.Guid == tagDef); + + tag.ImplicitTags.RemoveAll(td => td.Guid == implicitTagDef); + db.SaveChanges(); + } + + public void RemoveImplicitTag(TagDefinition tagDef, TagDefinition implicitTagDef) => + RemoveImplicitTag(tagDef, implicitTagDef); + public void CreateTagDefinition(string name, string? @namespace) { using var db = dbFactory.CreateDbContext(); @@ -91,20 +122,24 @@ public class TagService : ITagService { db.SaveChanges(); } - public void DeleteTagDefinition(TagDefinition tagDef) { + public void DeleteTagDefinition(Guid tagDef) { using var db = dbFactory.CreateDbContext(); - db.Entry(tagDef).State = EntityState.Unchanged; + + var tag = db.TagDefinitions.First(td => td.Guid == tagDef); using var transaction = db.Database.BeginTransaction(); db.Tags.RemoveRange( - db.Tags.Where(t => t.TagDefinition == tagDef)); - db.TagDefinitions.Remove(tagDef); + db.Tags.Where(t => t.TagDefinition.Guid == tagDef)); + db.TagDefinitions.Remove(tag); db.SaveChanges(); transaction.Commit(); } + public void DeleteTagDefinition(TagDefinition tagDef) => + DeleteTagDefinition(tagDef.Guid); + public void UpdateTagDefinition(Guid tagDef, string name, string? @namespace) { using var db = dbFactory.CreateDbContext(); @@ -122,11 +157,6 @@ public class TagService : ITagService { UpdateTagDefinition(tagDef.Guid, name, @namespace); public (TagDefinition tagDefinition, bool isImplicit)[] GetAllTags(Guid obj) { - IEnumerable GetTagRecursive(IEnumerable tagDefs) => - tagDefs - .Concat(tagDefs.SelectMany(td => GetTagRecursive(td.ImplicitTags))) - .DistinctBy(td => td.Guid); - using var db = dbFactory.CreateDbContext(); var @object = db.Objects.First(o => o.Guid == obj); @@ -139,4 +169,35 @@ public class TagService : ITagService { public (TagDefinition tagDefinition, bool isImplicit)[] GetAllTags(HBObject obj) => GetAllTags(obj.Guid); + + public (TagDefinition tagDefinition, bool isImplicit)[] GetAllTags(TagDefinition tagDef) { + using var db = dbFactory.CreateDbContext(); + + var tag = db.TagDefinitions.First(td => td.Guid == tagDef.Guid); + + return GetTagRecursive(tag.ImplicitTags) + .Select(td => new ValueTuple(td, !tag.ImplicitTags.Select(it => it.Guid).Contains(td.Guid))) + .ToArray(); + } + + private List GetTagRecursive(IEnumerable tagDefs) { + var tags = new List(tagDefs); + + List? toProcessNext = null; + + while(true) { + toProcessNext = (toProcessNext ?? tags) + .SelectMany(td => td.ImplicitTags) + .Where(td => !tags.Select(td => td.Guid).Contains(td.Guid)) + .DistinctBy(td => td.Guid) + .ToList(); + + tags.AddRange(toProcessNext); + + if(toProcessNext.Count() == 0) + break; + } + + return tags; + } } diff --git a/Services/UserStateService.cs b/Services/UserStateService.cs new file mode 100644 index 0000000..dc742e1 --- /dev/null +++ b/Services/UserStateService.cs @@ -0,0 +1,21 @@ +namespace HyperBooru.Services; + +public interface IUserStateService { + public bool ShowNsfw { get; set; } + + public event EventHandler ShowNsfwChanged; +} + +public class UserStateService : IUserStateService { + public bool ShowNsfw { + get => showNsfw; + set { + showNsfw = value; + ShowNsfwChanged?.Invoke(this, value); + } + } + + public event EventHandler ShowNsfwChanged; + + private bool showNsfw = false; +} -- cgit v1.3