Skip to content

Commit

Permalink
Merge pull request #802 from EdiWang/dev/webmention
Browse files Browse the repository at this point in the history
Webmention Phase 1: Shared Infrastructure
  • Loading branch information
EdiWang committed May 30, 2024
2 parents 1e1503e + fb7bd65 commit e080af4
Show file tree
Hide file tree
Showing 37 changed files with 321 additions and 236 deletions.
33 changes: 5 additions & 28 deletions Deployment/mssql-migration.sql
Original file line number Diff line number Diff line change
@@ -1,33 +1,10 @@
-- v14.3.x - v14.4.0
CREATE TABLE [dbo].[LoginHistory](
[Id] [int] IDENTITY(1,1) NOT NULL,
[LoginTimeUtc] [datetime] NOT NULL,
[LoginIp] [nvarchar](64) NULL,
[LoginUserAgent] [nvarchar](128) NULL,
[DeviceFingerprint] [nvarchar](128) NULL,
CONSTRAINT [PK_LoginHistory] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
-- v14.4.1 - v14.5.x

DROP TABLE [LocalAccount]
EXEC sp_rename 'Pingback', 'Mention'
GO

EXEC sys.sp_rename
@objname = N'Category.RouteName',
@newname = 'Slug',
@objtype = 'COLUMN'
ALTER TABLE Mention ADD Worker NVARCHAR(16)
GO

IF EXISTS (
SELECT 1
FROM sys.columns c
JOIN sys.objects o ON c.object_id = o.object_id
WHERE o.name = 'Post' AND c.name = 'InlineCss'
)
BEGIN
ALTER TABLE Post DROP COLUMN InlineCss;
END;
GO
UPDATE Mention SET Worker = N'Pingback'
GO
3 changes: 3 additions & 0 deletions src/Moonglade.Configuration/AdvancedSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ public class AdvancedSettings : IBlogSettings
[Display(Name = "Enable Pingback")]
public bool EnablePingback { get; set; } = true;

[Display(Name = "Enable Webmention")]
public bool EnableWebmention { get; set; } = true;

[Display(Name = "Enable OpenSearch")]
public bool EnableOpenSearch { get; set; } = true;

Expand Down
15 changes: 15 additions & 0 deletions src/Moonglade.Data.MySql/Configurations/MentionConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Moonglade.Data.Entities;

namespace Moonglade.Data.MySql.Configurations;


internal class MentionConfiguration : IEntityTypeConfiguration<MentionEntity>
{
public void Configure(EntityTypeBuilder<MentionEntity> builder)
{
builder.Property(e => e.Id).ValueGeneratedNever();
builder.Property(e => e.PingTimeUtc).HasColumnType("datetime");
}
}
20 changes: 0 additions & 20 deletions src/Moonglade.Data.MySql/Configurations/PingbackConfiguration.cs

This file was deleted.

2 changes: 1 addition & 1 deletion src/Moonglade.Data.MySql/MySqlBlogDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.ApplyConfiguration(new CommentReplyConfiguration());
modelBuilder.ApplyConfiguration(new PostConfiguration());
modelBuilder.ApplyConfiguration(new PostCategoryConfiguration());
modelBuilder.ApplyConfiguration(new PingbackConfiguration());
modelBuilder.ApplyConfiguration(new MentionConfiguration());
modelBuilder.ApplyConfiguration(new BlogThemeConfiguration());
modelBuilder.ApplyConfiguration(new BlogAssetConfiguration());
modelBuilder.ApplyConfiguration(new StyleSheetConfiguration());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Moonglade.Data.Entities;

namespace Moonglade.Data.PostgreSql.Configurations;


internal class MentionConfiguration : IEntityTypeConfiguration<MentionEntity>
{
public void Configure(EntityTypeBuilder<MentionEntity> builder)
{
builder.Property(e => e.Id).ValueGeneratedNever();
builder.Property(e => e.PingTimeUtc).HasColumnType("timestamp");
}
}

This file was deleted.

2 changes: 1 addition & 1 deletion src/Moonglade.Data.PostgreSql/PostgreSqlBlogDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.ApplyConfiguration(new PostConfiguration());
modelBuilder.ApplyConfiguration(new PostCategoryConfiguration());
modelBuilder.ApplyConfiguration(new LoginHistoryConfiguration());
modelBuilder.ApplyConfiguration(new PingbackConfiguration());
modelBuilder.ApplyConfiguration(new MentionConfiguration());
modelBuilder.ApplyConfiguration(new BlogThemeConfiguration());
modelBuilder.ApplyConfiguration(new BlogAssetConfiguration());
modelBuilder.ApplyConfiguration(new StyleSheetConfiguration());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Moonglade.Data.Entities;

namespace Moonglade.Data.SqlServer.Configurations;


internal class MentionConfiguration : IEntityTypeConfiguration<MentionEntity>
{
public void Configure(EntityTypeBuilder<MentionEntity> builder)
{
builder.Property(e => e.Id).ValueGeneratedNever();
builder.Property(e => e.PingTimeUtc).HasColumnType("datetime");
}
}

This file was deleted.

2 changes: 1 addition & 1 deletion src/Moonglade.Data.SqlServer/SqlServerBlogDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.ApplyConfiguration(new PostConfiguration());
modelBuilder.ApplyConfiguration(new PostCategoryConfiguration());
modelBuilder.ApplyConfiguration(new LoginHistoryConfiguration());
modelBuilder.ApplyConfiguration(new PingbackConfiguration());
modelBuilder.ApplyConfiguration(new MentionConfiguration());
modelBuilder.ApplyConfiguration(new BlogThemeConfiguration());
modelBuilder.ApplyConfiguration(new BlogAssetConfiguration());
modelBuilder.ApplyConfiguration(new StyleSheetConfiguration());
Expand Down
4 changes: 2 additions & 2 deletions src/Moonglade.Data/BlogDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public BlogDbContext(DbContextOptions options)
public virtual DbSet<FriendLinkEntity> FriendLink { get; set; }
public virtual DbSet<PageEntity> CustomPage { get; set; }
public virtual DbSet<LoginHistoryEntity> LoginHistory { get; set; }
public virtual DbSet<PingbackEntity> Pingback { get; set; }
public virtual DbSet<MentionEntity> Mention { get; set; }
public virtual DbSet<BlogThemeEntity> BlogTheme { get; set; }
public virtual DbSet<StyleSheetEntity> StyleSheet { get; set; }
public virtual DbSet<BlogAssetEntity> BlogAsset { get; set; }
Expand Down Expand Up @@ -62,7 +62,7 @@ public static async Task ClearAllData(this BlogDbContext context)
context.Tag.RemoveRange();
context.Comment.RemoveRange();
context.FriendLink.RemoveRange();
context.Pingback.RemoveRange();
context.Mention.RemoveRange();
context.Post.RemoveRange();
context.BlogConfiguration.RemoveRange();
context.BlogAsset.RemoveRange();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
namespace Moonglade.Data.Entities;
using System.ComponentModel.DataAnnotations;

public class PingbackEntity
namespace Moonglade.Data.Entities;

public class MentionEntity
{
public Guid Id { get; set; }

[MaxLength(256)]
public string Domain { get; set; }

[MaxLength(256)]
public string SourceUrl { get; set; }

[MaxLength(256)]
public string SourceTitle { get; set; }

[MaxLength(64)]
public string SourceIp { get; set; }

public Guid TargetPostId { get; set; }
public DateTime PingTimeUtc { get; set; }

[MaxLength(100)]
public string TargetPostTitle { get; set; }

[MaxLength(16)]
public string Worker { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Moonglade.Data.Specifications;

public sealed class PingbackReadOnlySpec : Specification<PingbackEntity>
public sealed class MentionReadOnlySpec : Specification<MentionEntity>
{
public PingbackReadOnlySpec()
public MentionReadOnlySpec()
{
Query.AsNoTracking();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Moonglade.Data.Specifications;

public sealed class PingbackSpec : Specification<PingbackEntity>
public sealed class MentionSpec : Specification<MentionEntity>
{
public PingbackSpec(Guid postId, string sourceUrl, string sourceIp)
public MentionSpec(Guid postId, string sourceUrl, string sourceIp)
{
Query.Where(p =>
p.TargetPostId == postId &&
Expand Down
12 changes: 12 additions & 0 deletions src/Moonglade.Mention.Common/ClearMentionsCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using MediatR;
using Moonglade.Data;
using Moonglade.Data.Entities;

namespace Moonglade.Mention.Common;

public record ClearMentionsCommand : IRequest;

public class ClearPingbackCommandHandler(MoongladeRepository<MentionEntity> repo) : IRequestHandler<ClearMentionsCommand>
{
public Task Handle(ClearMentionsCommand request, CancellationToken ct) => repo.Clear(ct);
}
19 changes: 19 additions & 0 deletions src/Moonglade.Mention.Common/DeleteMentionCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using MediatR;
using Moonglade.Data;
using Moonglade.Data.Entities;

namespace Moonglade.Mention.Common;

public record DeleteMentionCommand(Guid Id) : IRequest;

public class DeletePingbackCommandHandler(MoongladeRepository<MentionEntity> repo) : IRequestHandler<DeleteMentionCommand>
{
public async Task Handle(DeleteMentionCommand request, CancellationToken ct)
{
var entity = await repo.GetByIdAsync(request.Id, ct);
if (entity != null)
{
await repo.DeleteAsync(entity, ct);
}
}
}
15 changes: 15 additions & 0 deletions src/Moonglade.Mention.Common/GetMentionsQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using MediatR;
using Moonglade.Data;
using Moonglade.Data.Entities;
using Moonglade.Data.Specifications;

namespace Moonglade.Mention.Common;

public record GetMentionsQuery : IRequest<List<MentionEntity>>;

public class GetMentionsQueryHandler(MoongladeRepository<MentionEntity> repo) :
IRequestHandler<GetMentionsQuery, List<MentionEntity>>
{
public Task<List<MentionEntity>> Handle(GetMentionsQuery request, CancellationToken ct) =>
repo.ListAsync(new MentionReadOnlySpec(), ct);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Moonglade.Pingback;
namespace Moonglade.Mention.Common;

public record PingRequest
public record MentionRequest
{
public string SourceUrl { get; set; }

Expand All @@ -10,5 +10,5 @@ public record PingRequest

public bool ContainsHtml { get; set; }

public bool SourceHasLink { get; set; }
public bool SourceHasTarget { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
using System.Net;
using System.Text.RegularExpressions;

namespace Moonglade.Pingback;
namespace Moonglade.Mention.Common;

public interface IPingSourceInspector
public interface IMentionSourceInspector
{
Task<PingRequest> ExamineSourceAsync(string sourceUrl, string targetUrl);
Task<MentionRequest> ExamineSourceAsync(string sourceUrl, string targetUrl);
}

public class PingSourceInspector(ILogger<PingSourceInspector> logger, HttpClient httpClient) : IPingSourceInspector
public class MentionSourceInspector(ILogger<MentionSourceInspector> logger, HttpClient httpClient) : IMentionSourceInspector
{
public async Task<PingRequest> ExamineSourceAsync(string sourceUrl, string targetUrl)
public async Task<MentionRequest> ExamineSourceAsync(string sourceUrl, string targetUrl)
{
try
{
Expand All @@ -25,18 +25,18 @@ public async Task<PingRequest> ExamineSourceAsync(string sourceUrl, string targe
var html = await httpClient.GetStringAsync(sourceUrl);
var title = regexTitle.Match(html).Value.Trim();
var containsHtml = regexHtml.IsMatch(title);
var sourceHasLink = html.ToUpperInvariant().Contains(targetUrl.ToUpperInvariant());
var sourceHasTarget = html.ToUpperInvariant().Contains(targetUrl.TrimEnd('/').ToUpperInvariant());

var pingRequest = new PingRequest
var mentionRequest = new MentionRequest
{
Title = title,
ContainsHtml = containsHtml,
SourceHasLink = sourceHasLink,
SourceHasTarget = sourceHasTarget,
TargetUrl = targetUrl,
SourceUrl = sourceUrl
};

return pingRequest;
return mentionRequest;
}
catch (WebException ex)
{
Expand Down
Loading

0 comments on commit e080af4

Please sign in to comment.