Skip to content

Commit 39852ba

Browse files
authored
Merge pull request #452 from poppastring/email-alert-comment
Daily Email alert
2 parents 54c808a + fc275b8 commit 39852ba

File tree

13 files changed

+305
-443
lines changed

13 files changed

+305
-443
lines changed

source/DasBlog.CLI/DasBlog.CLI.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.0.0" />
2323
<PackageReference Include="Microsoft.Extensions.Configuration.Xml" Version="3.0.0" />
2424
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0" />
25-
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.0.0" />
25+
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.6" />
2626
<PackageReference Include="Microsoft.Extensions.Options" Version="3.0.0" />
2727
</ItemGroup>
2828

source/DasBlog.Services/ActivityLogs/EventCodes.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ public enum EventCodes : int
5353
EditUser,
5454
DeleteUser,
5555
RSS = 7000,
56-
Site,
56+
Site = 8000,
57+
HttpReferrer = 10000,
58+
HttpUserAgent = 10001,
59+
HttpUserDomain = 10002,
5760
ApplicationStartup = 32000,
5861

5962
}

source/DasBlog.Services/DasBlog.Services.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<PackageReference Include="Kveer.XmlRPC" Version="1.1.1" />
1111
<PackageReference Include="MailKit" Version="2.4.1" />
1212
<PackageReference Include="Microsoft.Extensions.Options" Version="3.0.0" />
13+
<PackageReference Include="Quartz.AspNetCore" Version="3.1.0" />
1314
</ItemGroup>
1415
<ItemGroup>
1516
<FrameworkReference Include="Microsoft.AspNetCore.App" />

source/DasBlog.Services/IDasBlogSettings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Net.Mail;
23
using DasBlog.Core.Security;
34
using DasBlog.Services.ConfigFile.Interfaces;
45
using newtelligence.DasBlog.Runtime;
@@ -44,5 +45,6 @@ public interface IDasBlogSettings
4445
string CompressTitle(string title);
4546
bool IsAdmin(string gravatarhash);
4647
string GeneratePostUrl(Entry entry);
48+
SendMailInfo GetMailInfo(MailMessage emailmessage);
4749
}
4850
}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
using System;
2+
using System.Data;
3+
using System.Linq;
4+
using System.Net.Mail;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using DasBlog.Services.ActivityLogs;
8+
using Microsoft.Extensions.Logging;
9+
using newtelligence.DasBlog.Runtime;
10+
using Quartz;
11+
12+
namespace DasBlog.Services.Scheduler
13+
{
14+
public class SiteEmailReport : IJob
15+
{
16+
private readonly ILogger<SiteEmailReport> logger;
17+
private readonly IActivityService activityService;
18+
private readonly IDasBlogSettings dasBlogSettings;
19+
private readonly DateTime midnight;
20+
21+
private const string MAIN_HEADER_TABLE = "<html><table><tbody><tr><td class='x_mainheader' width='100%'>{0}</td></tr></tbody></table>";
22+
private const string TABLE = "<table width='100%'><tbody>{0}</tbody></table>";
23+
private const string TABLE_HEADER_ROW = "<tr><td class='x_data' width='90%'><b>{0}</b></td><td class='x_data' width='10%'><b>{1}</b></td></tr>";
24+
private const string TABLE_BODY_ROW = "<tr><td class='x_data'>{0}</td><td class='x_data'>{1}</td></tr>";
25+
private const string HTML_CLOSE_TAG = "</html>";
26+
private readonly string EMAIL_TITLE = string.Empty;
27+
28+
public SiteEmailReport(ILogger<SiteEmailReport> logger, IActivityService activityService, IDasBlogSettings dasBlogSettings)
29+
{
30+
this.logger = logger;
31+
this.activityService = activityService;
32+
this.dasBlogSettings = dasBlogSettings;
33+
midnight = DateTime.Now.Date;
34+
EMAIL_TITLE = string.Format("Weblog Daily Activity Report for {0}, {1}", midnight.DayOfWeek, midnight.ToString("MMMM dd, yyyy"));
35+
}
36+
37+
public async Task Execute(IJobExecutionContext context)
38+
{
39+
if(dasBlogSettings.SiteConfiguration.EnableDailyReportEmail)
40+
{
41+
logger.LogInformation(context.JobDetail.Key + " job executing, triggered by " + context.Trigger.Key);
42+
43+
var emailbody = FormatEmail();
44+
45+
var emailinfo = ComposeMail(emailbody);
46+
47+
try
48+
{
49+
emailinfo?.SendMyMessage();
50+
}
51+
catch (Exception ex)
52+
{
53+
logger.LogError(new ActivityLogs.EventDataItem(ActivityLogs.EventCodes.SmtpError,
54+
new Uri(dasBlogSettings.SiteConfiguration.Root),
55+
string.Format("Weblog Daily Activity Report Failed: {0}", ex.Message)));
56+
}
57+
}
58+
59+
await Task.Delay(TimeSpan.FromMilliseconds(1));
60+
}
61+
62+
private string FormatEmail()
63+
{
64+
var body = new StringBuilder();
65+
var table = new StringBuilder();
66+
var events = activityService.GetEventsForDay(midnight);
67+
68+
//header
69+
body.Append(string.Format(MAIN_HEADER_TABLE, EMAIL_TITLE));
70+
71+
//summary header
72+
table.Append(string.Format(TABLE_HEADER_ROW, "Summary", "Hits"));
73+
table.Append(string.Format(TABLE_BODY_ROW, "Referrer", events.Count(e => e.EventCode == ActivityLogs.EventCodes.HttpReferrer)));
74+
table.Append(string.Format(TABLE_BODY_ROW, "User Agents", events.Count(e => e.EventCode == ActivityLogs.EventCodes.HttpUserAgent)));
75+
table.Append(string.Format(TABLE_BODY_ROW, "Domain", events.Count(e => e.EventCode == ActivityLogs.EventCodes.HttpUserDomain)));
76+
77+
body.Append(string.Format(TABLE, table.ToString()));
78+
79+
//Referrer
80+
table.Clear();
81+
table.Append(string.Format(TABLE_HEADER_ROW, "Referrer", "Count"));
82+
83+
var referrer = events.Where(x => x.EventCode == ActivityLogs.EventCodes.HttpReferrer)
84+
.GroupBy(info => info.HtmlMessage)
85+
.Select(group => new { Referrer = group.Key, Count = group.Count() })
86+
.OrderBy(y => y.Count);
87+
88+
foreach (var row in referrer)
89+
{
90+
table.Append(string.Format(TABLE_BODY_ROW, row.Referrer, row.Count));
91+
}
92+
93+
body.Append(string.Format(TABLE, table.ToString()));
94+
95+
//User Agents
96+
table.Clear();
97+
table.Append(string.Format(TABLE_HEADER_ROW, "User Agents", "Count"));
98+
99+
var useragent = events.Where(x => x.EventCode == ActivityLogs.EventCodes.HttpUserAgent)
100+
.GroupBy(info => info.HtmlMessage)
101+
.Select(group => new { Referrer = group.Key, Count = group.Count() })
102+
.OrderBy(y => y.Count);
103+
104+
foreach (var row in useragent)
105+
{
106+
table.Append(string.Format(TABLE_BODY_ROW, row.Referrer, row.Count));
107+
}
108+
109+
body.Append(string.Format(TABLE, table.ToString()));
110+
111+
//Domain
112+
table.Clear();
113+
table.Append(string.Format(TABLE_HEADER_ROW, "Domain", "Count"));
114+
115+
var domain = events.Where(x => x.EventCode == ActivityLogs.EventCodes.HttpUserDomain)
116+
.GroupBy(info => info.HtmlMessage)
117+
.Select(group => new { Referrer = group.Key, Count = group.Count() })
118+
.OrderBy(y => y.Count);
119+
120+
foreach (var row in domain)
121+
{
122+
table.Append(string.Format(TABLE_BODY_ROW, row.Referrer, row.Count));
123+
}
124+
125+
body.Append(string.Format(TABLE, table.ToString()));
126+
127+
body.Append(HTML_CLOSE_TAG);
128+
129+
return body.ToString();
130+
}
131+
132+
private SendMailInfo ComposeMail(string body)
133+
{
134+
var emailMessage = new MailMessage();
135+
136+
if (!string.IsNullOrWhiteSpace(dasBlogSettings.SiteConfiguration.NotificationEMailAddress))
137+
{
138+
emailMessage.To.Add(dasBlogSettings.SiteConfiguration.NotificationEMailAddress);
139+
}
140+
else
141+
{
142+
if (!string.IsNullOrWhiteSpace(dasBlogSettings.SiteConfiguration.Contact))
143+
{
144+
emailMessage.To.Add(dasBlogSettings.SiteConfiguration.Contact);
145+
}
146+
else
147+
{
148+
return null;
149+
}
150+
}
151+
152+
emailMessage.Subject = string.Format("Weblog Daily Activity Report for {0}, {1}", midnight.DayOfWeek, midnight.ToString("MMMM dd, yyyy"));
153+
154+
emailMessage.Body = body;
155+
156+
emailMessage.IsBodyHtml = true;
157+
emailMessage.BodyEncoding = Encoding.UTF8;
158+
159+
if (!string.IsNullOrWhiteSpace(dasBlogSettings.SiteConfiguration.SmtpUserName))
160+
{
161+
emailMessage.From = new MailAddress(dasBlogSettings.SiteConfiguration.SmtpUserName);
162+
}
163+
else
164+
{
165+
return null;
166+
}
167+
168+
return dasBlogSettings.GetMailInfo(emailMessage);
169+
}
170+
171+
172+
}
173+
}

source/DasBlog.Tests/UnitTests/DasBlogSettingTest.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Xml.Serialization;
1010
using DasBlog.Services;
1111
using newtelligence.DasBlog.Runtime;
12+
using System.Net.Mail;
1213

1314
namespace DasBlog.Tests.UnitTests
1415
{
@@ -244,5 +245,10 @@ public string GeneratePostUrl(Entry entry)
244245

245246
return link;
246247
}
248+
249+
public SendMailInfo GetMailInfo(MailMessage emailmessage)
250+
{
251+
throw new NotImplementedException();
252+
}
247253
}
248254
}

source/DasBlog.Web.Repositories/BlogManager.cs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ public bool SendTestEmail()
455455
emailMessage.Subject = string.Format("SMTP email from {0}", dasBlogSettings.SiteConfiguration.Title);
456456
emailMessage.Body = "Test ";
457457

458-
var sendMailInfo = GetMailInfo(emailMessage);
458+
var sendMailInfo = dasBlogSettings.GetMailInfo(emailMessage);
459459

460460
try
461461
{
@@ -531,15 +531,7 @@ private SendMailInfo ComposeMail(Comment c)
531531

532532
emailMessage.From = new MailAddress(dasBlogSettings.SiteConfiguration.SmtpUserName);
533533

534-
return GetMailInfo(emailMessage);
535-
}
536-
537-
private SendMailInfo GetMailInfo(MailMessage emailmessage)
538-
{
539-
return new SendMailInfo(emailmessage, dasBlogSettings.SiteConfiguration.SmtpServer,
540-
dasBlogSettings.SiteConfiguration.EnableSmtpAuthentication, dasBlogSettings.SiteConfiguration.UseSSLForSMTP,
541-
dasBlogSettings.SiteConfiguration.SmtpUserName, dasBlogSettings.SiteConfiguration.SmtpPassword,
542-
dasBlogSettings.SiteConfiguration.SmtpPort);
534+
return dasBlogSettings.GetMailInfo(emailMessage);
543535
}
544536
}
545537
}

source/DasBlog.Web.UI/DasBlog.Web.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.9.10" />
2323
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.0.0" />
2424
<PackageReference Include="NetEscapades.Extensions.Logging.RollingFile" Version="2.2.0" />
25+
<PackageReference Include="Quartz.AspNetCore" Version="3.1.0" />
2526
</ItemGroup>
2627
<ItemGroup>
2728
<ProjectReference Include="..\DasBlog.CLI\DasBlog.CLI.csproj" />
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using DasBlog.Services;
6+
using DasBlog.Services.ActivityLogs;
7+
using Microsoft.AspNetCore.Builder;
8+
using Microsoft.AspNetCore.Http;
9+
using Microsoft.Extensions.Logging;
10+
using Quartz.Util;
11+
12+
namespace DasBlog.Web.Services
13+
{
14+
public class LoggingAgent
15+
{
16+
private readonly ILogger<LoggingAgent> logger;
17+
private readonly RequestDelegate _next;
18+
19+
public LoggingAgent(RequestDelegate next, ILogger<LoggingAgent> logger)
20+
{
21+
_next = next;
22+
this.logger = logger;
23+
}
24+
25+
public async Task Invoke(HttpContext context)
26+
{
27+
try
28+
{
29+
if (!context.Request.Headers["User-Agent"].ToString().IsNullOrWhiteSpace())
30+
{
31+
logger.LogInformation(new EventDataItem(EventCodes.HttpUserAgent, null, context.Request.Headers["User-Agent"].ToString()));
32+
}
33+
34+
if (!context.Request.Headers["Referrer"].ToString().IsNullOrWhiteSpace())
35+
{
36+
logger.LogInformation(new EventDataItem(EventCodes.HttpReferrer, null, context.Request.Headers["Referrer"].ToString()));
37+
}
38+
39+
if (!context.Request.HttpContext.Connection.RemoteIpAddress.ToString().IsNullOrWhiteSpace())
40+
{
41+
logger.LogInformation(new EventDataItem(EventCodes.HttpReferrer, null, context.Request.HttpContext.Connection.RemoteIpAddress.ToString()));
42+
}
43+
}
44+
catch (Exception ex)
45+
{
46+
logger.LogError(new EventDataItem(EventCodes.Error, null, string.Format("Logging Agent Exception:{0}", ex.Message)));
47+
}
48+
49+
await _next.Invoke(context);
50+
}
51+
}
52+
53+
public static class MiddlewareExtensions
54+
{
55+
public static IApplicationBuilder UseLoggingAgent(this IApplicationBuilder builder)
56+
{
57+
return builder.UseMiddleware<LoggingAgent>();
58+
}
59+
}
60+
61+
62+
}

0 commit comments

Comments
 (0)