From bfc4dcb4fd35a424f941700346a4e6f5ad6726fb Mon Sep 17 00:00:00 2001 From: Nicolas Constant Date: Fri, 31 Jul 2020 22:13:52 -0400 Subject: [PATCH] extracting tags --- .../Models/ActivityCreateNote.cs | 1 + src/BirdsiteLive.ActivityPub/Models/Note.cs | 8 ++-- src/BirdsiteLive.ActivityPub/Models/Tag.cs | 8 ++++ src/BirdsiteLive.Domain/ActivityPubService.cs | 1 + src/BirdsiteLive.Domain/StatusService.cs | 35 +++++++++++++- .../Tools/StatusExtractor.cs | 7 +++ src/BirdsiteLive.sln | 9 +++- .../Controllers/DebugingController.cs | 1 + .../BirdsiteLive.Domain.Tests.csproj | 20 ++++++++ .../StatusServiceTests.cs | 48 +++++++++++++++++++ 10 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 src/BirdsiteLive.ActivityPub/Models/Tag.cs create mode 100644 src/BirdsiteLive.Domain/Tools/StatusExtractor.cs create mode 100644 src/Tests/BirdsiteLive.Domain.Tests/BirdsiteLive.Domain.Tests.csproj create mode 100644 src/Tests/BirdsiteLive.Domain.Tests/StatusServiceTests.cs diff --git a/src/BirdsiteLive.ActivityPub/Models/ActivityCreateNote.cs b/src/BirdsiteLive.ActivityPub/Models/ActivityCreateNote.cs index d100b3a..fe14ac7 100644 --- a/src/BirdsiteLive.ActivityPub/Models/ActivityCreateNote.cs +++ b/src/BirdsiteLive.ActivityPub/Models/ActivityCreateNote.cs @@ -1,4 +1,5 @@ using System; +using BirdsiteLive.ActivityPub.Models; using Newtonsoft.Json; namespace BirdsiteLive.ActivityPub diff --git a/src/BirdsiteLive.ActivityPub/Models/Note.cs b/src/BirdsiteLive.ActivityPub/Models/Note.cs index b0aba5e..fc6dc5b 100644 --- a/src/BirdsiteLive.ActivityPub/Models/Note.cs +++ b/src/BirdsiteLive.ActivityPub/Models/Note.cs @@ -1,9 +1,7 @@ -using System; -using System.Collections.Generic; -using BirdsiteLive.ActivityPub.Converters; +using BirdsiteLive.ActivityPub.Converters; using Newtonsoft.Json; -namespace BirdsiteLive.ActivityPub +namespace BirdsiteLive.ActivityPub.Models { public class Note { @@ -25,7 +23,7 @@ namespace BirdsiteLive.ActivityPub public string content { get; set; } //public Dictionary contentMap { get; set; } public Attachment[] attachment { get; set; } - public string[] tag { get; set; } + public Tag[] tag { get; set; } //public Dictionary replies; } } \ No newline at end of file diff --git a/src/BirdsiteLive.ActivityPub/Models/Tag.cs b/src/BirdsiteLive.ActivityPub/Models/Tag.cs new file mode 100644 index 0000000..0699c97 --- /dev/null +++ b/src/BirdsiteLive.ActivityPub/Models/Tag.cs @@ -0,0 +1,8 @@ +namespace BirdsiteLive.ActivityPub.Models +{ + public class Tag { + public string type { get; set; } //Hashtag + public string href { get; set; } //https://mastodon.social/tags/app + public string name { get; set; } //#app + } +} \ No newline at end of file diff --git a/src/BirdsiteLive.Domain/ActivityPubService.cs b/src/BirdsiteLive.Domain/ActivityPubService.cs index 9f6e8e5..b9b248e 100644 --- a/src/BirdsiteLive.Domain/ActivityPubService.cs +++ b/src/BirdsiteLive.Domain/ActivityPubService.cs @@ -4,6 +4,7 @@ using System.Net.Http; using System.Text; using System.Threading.Tasks; using BirdsiteLive.ActivityPub; +using BirdsiteLive.ActivityPub.Models; using BirdsiteLive.Common.Settings; using Newtonsoft.Json; using Org.BouncyCastle.Bcpg; diff --git a/src/BirdsiteLive.Domain/StatusService.cs b/src/BirdsiteLive.Domain/StatusService.cs index e50dddb..32e7f30 100644 --- a/src/BirdsiteLive.Domain/StatusService.cs +++ b/src/BirdsiteLive.Domain/StatusService.cs @@ -2,7 +2,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.RegularExpressions; using BirdsiteLive.ActivityPub; +using BirdsiteLive.ActivityPub.Models; using BirdsiteLive.Common.Settings; using BirdsiteLive.Twitter.Models; using Tweetinvi.Models; @@ -35,6 +37,8 @@ namespace BirdsiteLive.Domain var to = $"{actorUrl}/followers"; var apPublic = "https://www.w3.org/ns/activitystreams#Public"; + var extractedTags = ExtractTags(tweet.MessageContent); + var note = new Note { id = $"{noteId}/activity", @@ -51,17 +55,44 @@ namespace BirdsiteLive.Domain //cc = new string[0], sensitive = false, - content = $"

{tweet.MessageContent}

", + content = $"

{extractedTags.content}

", attachment = Convert(tweet.Media), - tag = new string[0] + tag = extractedTags.tags }; return note; } + private (string content, Tag[] tags) ExtractTags(string messageContent) + { + var regex = new Regex(@"\W(\#[a-zA-Z0-9]+\b)(?!;)"); + var match = regex.Matches(messageContent); + + var tags = new List(); + foreach (var m in match) + { + var tag = m.ToString().Replace("#", string.Empty).Replace("\n", string.Empty).Trim(); + var url = $"https://{_instanceSettings.Domain}/tags/{tag}"; + + tags.Add(new Tag + { + name = $"#{tag}", + href = url, + type = "Hashtag" + }); + + messageContent = messageContent.Replace( + $"#{tag}", + $@"#{tag}"); + } + + return (messageContent, new Tag[0]); + } + private Attachment[] Convert(ExtractedMedia[] media) { + if(media == null) return new Attachment[0]; return media.Select(x => { return new Attachment diff --git a/src/BirdsiteLive.Domain/Tools/StatusExtractor.cs b/src/BirdsiteLive.Domain/Tools/StatusExtractor.cs new file mode 100644 index 0000000..ed8951a --- /dev/null +++ b/src/BirdsiteLive.Domain/Tools/StatusExtractor.cs @@ -0,0 +1,7 @@ +namespace BirdsiteLive.Domain.Tools +{ + public class StatusExtractor + { + + } +} \ No newline at end of file diff --git a/src/BirdsiteLive.sln b/src/BirdsiteLive.sln index 5491d81..6ef9eb6 100644 --- a/src/BirdsiteLive.sln +++ b/src/BirdsiteLive.sln @@ -33,7 +33,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BirdsiteLive.DAL.Postgres.T EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Pipeline", "Pipeline", "{DA3C160C-4811-4E26-A5AD-42B81FAF2D7C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BirdsiteLive.Pipeline", "BirdsiteLive.Pipeline\BirdsiteLive.Pipeline.csproj", "{2A8CC30D-D775-47D1-9388-F72A5C32DE2A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BirdsiteLive.Pipeline", "BirdsiteLive.Pipeline\BirdsiteLive.Pipeline.csproj", "{2A8CC30D-D775-47D1-9388-F72A5C32DE2A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BirdsiteLive.Domain.Tests", "Tests\BirdsiteLive.Domain.Tests\BirdsiteLive.Domain.Tests.csproj", "{F544D745-89A8-4DEA-B61C-A7E6C53C1D63}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -89,6 +91,10 @@ Global {2A8CC30D-D775-47D1-9388-F72A5C32DE2A}.Debug|Any CPU.Build.0 = Debug|Any CPU {2A8CC30D-D775-47D1-9388-F72A5C32DE2A}.Release|Any CPU.ActiveCfg = Release|Any CPU {2A8CC30D-D775-47D1-9388-F72A5C32DE2A}.Release|Any CPU.Build.0 = Release|Any CPU + {F544D745-89A8-4DEA-B61C-A7E6C53C1D63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F544D745-89A8-4DEA-B61C-A7E6C53C1D63}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F544D745-89A8-4DEA-B61C-A7E6C53C1D63}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F544D745-89A8-4DEA-B61C-A7E6C53C1D63}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -105,6 +111,7 @@ Global {87E46519-BBF2-437C-8A5B-CF6CDE7CDAA6} = {CFAB3509-3931-42DB-AC97-4F91FC2D849C} {CD9489BF-69C8-4705-8774-81C45F4F8FE1} = {A32D3458-09D0-4E0A-BA4B-8C411B816B94} {2A8CC30D-D775-47D1-9388-F72A5C32DE2A} = {DA3C160C-4811-4E26-A5AD-42B81FAF2D7C} + {F544D745-89A8-4DEA-B61C-A7E6C53C1D63} = {A32D3458-09D0-4E0A-BA4B-8C411B816B94} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {69E8DCAD-4C37-4010-858F-5F94E6FBABCE} diff --git a/src/BirdsiteLive/Controllers/DebugingController.cs b/src/BirdsiteLive/Controllers/DebugingController.cs index 164bb24..cb67a6e 100644 --- a/src/BirdsiteLive/Controllers/DebugingController.cs +++ b/src/BirdsiteLive/Controllers/DebugingController.cs @@ -5,6 +5,7 @@ using System.Net.Http; using System.Text; using System.Threading.Tasks; using BirdsiteLive.ActivityPub; +using BirdsiteLive.ActivityPub.Models; using BirdsiteLive.Common.Settings; using BirdsiteLive.Domain; using Microsoft.AspNetCore.Mvc; diff --git a/src/Tests/BirdsiteLive.Domain.Tests/BirdsiteLive.Domain.Tests.csproj b/src/Tests/BirdsiteLive.Domain.Tests/BirdsiteLive.Domain.Tests.csproj new file mode 100644 index 0000000..8762be8 --- /dev/null +++ b/src/Tests/BirdsiteLive.Domain.Tests/BirdsiteLive.Domain.Tests.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + + + + diff --git a/src/Tests/BirdsiteLive.Domain.Tests/StatusServiceTests.cs b/src/Tests/BirdsiteLive.Domain.Tests/StatusServiceTests.cs new file mode 100644 index 0000000..b1f3f6f --- /dev/null +++ b/src/Tests/BirdsiteLive.Domain.Tests/StatusServiceTests.cs @@ -0,0 +1,48 @@ +using System; +using BirdsiteLive.Common.Settings; +using BirdsiteLive.Twitter.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace BirdsiteLive.Domain.Tests +{ + [TestClass] + public class StatusServiceTests + { + private readonly InstanceSettings _settings; + + #region Ctor + public StatusServiceTests() + { + _settings = new InstanceSettings + { + Domain = "domain.name" + }; + } + #endregion + + [TestMethod] + public void ExtractMentionsTest() + { + #region Stubs + var username = "MyUserName"; + var extractedTweet = new ExtractedTweet + { + Id = 124L, + CreatedAt = DateTime.UtcNow, + MessageContent = @"Getting ready for the weekend...have a great one everyone! +⁠ +Photo by Tim Tronckoe | @timtronckoe +⁠ +#archenemy #michaelamott #alissawhitegluz #jeffloomis #danielerlandsson #sharleedangelo⁠" + }; + #endregion + + var service = new StatusService(_settings); + var result = service.GetStatus(username, extractedTweet); + + #region Validations + + #endregion + } + } +}