diff --git a/source/DasBlog.CLI/DasBlog.CLI.csproj b/source/DasBlog.CLI/DasBlog.CLI.csproj index 62067dba..94bee897 100644 --- a/source/DasBlog.CLI/DasBlog.CLI.csproj +++ b/source/DasBlog.CLI/DasBlog.CLI.csproj @@ -22,7 +22,7 @@ - + diff --git a/source/DasBlog.Services/ActivityLogs/EventCodes.cs b/source/DasBlog.Services/ActivityLogs/EventCodes.cs index 7bc9d320..d3d5ef12 100644 --- a/source/DasBlog.Services/ActivityLogs/EventCodes.cs +++ b/source/DasBlog.Services/ActivityLogs/EventCodes.cs @@ -53,7 +53,10 @@ public enum EventCodes : int EditUser, DeleteUser, RSS = 7000, - Site, + Site = 8000, + HttpReferrer = 10000, + HttpUserAgent = 10001, + HttpUserDomain = 10002, ApplicationStartup = 32000, } diff --git a/source/DasBlog.Services/DasBlog.Services.csproj b/source/DasBlog.Services/DasBlog.Services.csproj index 69bd022f..cb63b89f 100644 --- a/source/DasBlog.Services/DasBlog.Services.csproj +++ b/source/DasBlog.Services/DasBlog.Services.csproj @@ -10,6 +10,7 @@ + diff --git a/source/DasBlog.Services/IDasBlogSettings.cs b/source/DasBlog.Services/IDasBlogSettings.cs index e60d47cb..95f41a33 100644 --- a/source/DasBlog.Services/IDasBlogSettings.cs +++ b/source/DasBlog.Services/IDasBlogSettings.cs @@ -1,4 +1,5 @@ using System; +using System.Net.Mail; using DasBlog.Core.Security; using DasBlog.Services.ConfigFile.Interfaces; using newtelligence.DasBlog.Runtime; @@ -44,5 +45,6 @@ public interface IDasBlogSettings string CompressTitle(string title); bool IsAdmin(string gravatarhash); string GeneratePostUrl(Entry entry); + SendMailInfo GetMailInfo(MailMessage emailmessage); } } diff --git a/source/DasBlog.Services/Scheduler/SiteReport.cs b/source/DasBlog.Services/Scheduler/SiteReport.cs new file mode 100644 index 00000000..ed15154d --- /dev/null +++ b/source/DasBlog.Services/Scheduler/SiteReport.cs @@ -0,0 +1,173 @@ +using System; +using System.Data; +using System.Linq; +using System.Net.Mail; +using System.Text; +using System.Threading.Tasks; +using DasBlog.Services.ActivityLogs; +using Microsoft.Extensions.Logging; +using newtelligence.DasBlog.Runtime; +using Quartz; + +namespace DasBlog.Services.Scheduler +{ + public class SiteEmailReport : IJob + { + private readonly ILogger logger; + private readonly IActivityService activityService; + private readonly IDasBlogSettings dasBlogSettings; + private readonly DateTime midnight; + + private const string MAIN_HEADER_TABLE = "
{0}
"; + private const string TABLE = "{0}
"; + private const string TABLE_HEADER_ROW = "{0}{1}"; + private const string TABLE_BODY_ROW = "{0}{1}"; + private const string HTML_CLOSE_TAG = ""; + private readonly string EMAIL_TITLE = string.Empty; + + public SiteEmailReport(ILogger logger, IActivityService activityService, IDasBlogSettings dasBlogSettings) + { + this.logger = logger; + this.activityService = activityService; + this.dasBlogSettings = dasBlogSettings; + midnight = DateTime.Now.Date; + EMAIL_TITLE = string.Format("Weblog Daily Activity Report for {0}, {1}", midnight.DayOfWeek, midnight.ToString("MMMM dd, yyyy")); + } + + public async Task Execute(IJobExecutionContext context) + { + if(dasBlogSettings.SiteConfiguration.EnableDailyReportEmail) + { + logger.LogInformation(context.JobDetail.Key + " job executing, triggered by " + context.Trigger.Key); + + var emailbody = FormatEmail(); + + var emailinfo = ComposeMail(emailbody); + + try + { + emailinfo?.SendMyMessage(); + } + catch (Exception ex) + { + logger.LogError(new ActivityLogs.EventDataItem(ActivityLogs.EventCodes.SmtpError, + new Uri(dasBlogSettings.SiteConfiguration.Root), + string.Format("Weblog Daily Activity Report Failed: {0}", ex.Message))); + } + } + + await Task.Delay(TimeSpan.FromMilliseconds(1)); + } + + private string FormatEmail() + { + var body = new StringBuilder(); + var table = new StringBuilder(); + var events = activityService.GetEventsForDay(midnight); + + //header + body.Append(string.Format(MAIN_HEADER_TABLE, EMAIL_TITLE)); + + //summary header + table.Append(string.Format(TABLE_HEADER_ROW, "Summary", "Hits")); + table.Append(string.Format(TABLE_BODY_ROW, "Referrer", events.Count(e => e.EventCode == ActivityLogs.EventCodes.HttpReferrer))); + table.Append(string.Format(TABLE_BODY_ROW, "User Agents", events.Count(e => e.EventCode == ActivityLogs.EventCodes.HttpUserAgent))); + table.Append(string.Format(TABLE_BODY_ROW, "Domain", events.Count(e => e.EventCode == ActivityLogs.EventCodes.HttpUserDomain))); + + body.Append(string.Format(TABLE, table.ToString())); + + //Referrer + table.Clear(); + table.Append(string.Format(TABLE_HEADER_ROW, "Referrer", "Count")); + + var referrer = events.Where(x => x.EventCode == ActivityLogs.EventCodes.HttpReferrer) + .GroupBy(info => info.HtmlMessage) + .Select(group => new { Referrer = group.Key, Count = group.Count() }) + .OrderBy(y => y.Count); + + foreach (var row in referrer) + { + table.Append(string.Format(TABLE_BODY_ROW, row.Referrer, row.Count)); + } + + body.Append(string.Format(TABLE, table.ToString())); + + //User Agents + table.Clear(); + table.Append(string.Format(TABLE_HEADER_ROW, "User Agents", "Count")); + + var useragent = events.Where(x => x.EventCode == ActivityLogs.EventCodes.HttpUserAgent) + .GroupBy(info => info.HtmlMessage) + .Select(group => new { Referrer = group.Key, Count = group.Count() }) + .OrderBy(y => y.Count); + + foreach (var row in useragent) + { + table.Append(string.Format(TABLE_BODY_ROW, row.Referrer, row.Count)); + } + + body.Append(string.Format(TABLE, table.ToString())); + + //Domain + table.Clear(); + table.Append(string.Format(TABLE_HEADER_ROW, "Domain", "Count")); + + var domain = events.Where(x => x.EventCode == ActivityLogs.EventCodes.HttpUserDomain) + .GroupBy(info => info.HtmlMessage) + .Select(group => new { Referrer = group.Key, Count = group.Count() }) + .OrderBy(y => y.Count); + + foreach (var row in domain) + { + table.Append(string.Format(TABLE_BODY_ROW, row.Referrer, row.Count)); + } + + body.Append(string.Format(TABLE, table.ToString())); + + body.Append(HTML_CLOSE_TAG); + + return body.ToString(); + } + + private SendMailInfo ComposeMail(string body) + { + var emailMessage = new MailMessage(); + + if (!string.IsNullOrWhiteSpace(dasBlogSettings.SiteConfiguration.NotificationEMailAddress)) + { + emailMessage.To.Add(dasBlogSettings.SiteConfiguration.NotificationEMailAddress); + } + else + { + if (!string.IsNullOrWhiteSpace(dasBlogSettings.SiteConfiguration.Contact)) + { + emailMessage.To.Add(dasBlogSettings.SiteConfiguration.Contact); + } + else + { + return null; + } + } + + emailMessage.Subject = string.Format("Weblog Daily Activity Report for {0}, {1}", midnight.DayOfWeek, midnight.ToString("MMMM dd, yyyy")); + + emailMessage.Body = body; + + emailMessage.IsBodyHtml = true; + emailMessage.BodyEncoding = Encoding.UTF8; + + if (!string.IsNullOrWhiteSpace(dasBlogSettings.SiteConfiguration.SmtpUserName)) + { + emailMessage.From = new MailAddress(dasBlogSettings.SiteConfiguration.SmtpUserName); + } + else + { + return null; + } + + return dasBlogSettings.GetMailInfo(emailMessage); + } + + + } +} diff --git a/source/DasBlog.Tests/UnitTests/DasBlogSettingTest.cs b/source/DasBlog.Tests/UnitTests/DasBlogSettingTest.cs index b79577bc..c5b00ade 100644 --- a/source/DasBlog.Tests/UnitTests/DasBlogSettingTest.cs +++ b/source/DasBlog.Tests/UnitTests/DasBlogSettingTest.cs @@ -9,6 +9,7 @@ using System.Xml.Serialization; using DasBlog.Services; using newtelligence.DasBlog.Runtime; +using System.Net.Mail; namespace DasBlog.Tests.UnitTests { @@ -244,5 +245,10 @@ public string GeneratePostUrl(Entry entry) return link; } + + public SendMailInfo GetMailInfo(MailMessage emailmessage) + { + throw new NotImplementedException(); + } } } diff --git a/source/DasBlog.Web.Repositories/BlogManager.cs b/source/DasBlog.Web.Repositories/BlogManager.cs index b6a68969..b8b2945d 100644 --- a/source/DasBlog.Web.Repositories/BlogManager.cs +++ b/source/DasBlog.Web.Repositories/BlogManager.cs @@ -455,7 +455,7 @@ public bool SendTestEmail() emailMessage.Subject = string.Format("SMTP email from {0}", dasBlogSettings.SiteConfiguration.Title); emailMessage.Body = "Test "; - var sendMailInfo = GetMailInfo(emailMessage); + var sendMailInfo = dasBlogSettings.GetMailInfo(emailMessage); try { @@ -531,15 +531,7 @@ private SendMailInfo ComposeMail(Comment c) emailMessage.From = new MailAddress(dasBlogSettings.SiteConfiguration.SmtpUserName); - return GetMailInfo(emailMessage); - } - - private SendMailInfo GetMailInfo(MailMessage emailmessage) - { - return new SendMailInfo(emailmessage, dasBlogSettings.SiteConfiguration.SmtpServer, - dasBlogSettings.SiteConfiguration.EnableSmtpAuthentication, dasBlogSettings.SiteConfiguration.UseSSLForSMTP, - dasBlogSettings.SiteConfiguration.SmtpUserName, dasBlogSettings.SiteConfiguration.SmtpPassword, - dasBlogSettings.SiteConfiguration.SmtpPort); + return dasBlogSettings.GetMailInfo(emailMessage); } } } diff --git a/source/DasBlog.Web.UI/DasBlog.Web.csproj b/source/DasBlog.Web.UI/DasBlog.Web.csproj index c429bada..7c6c3279 100644 --- a/source/DasBlog.Web.UI/DasBlog.Web.csproj +++ b/source/DasBlog.Web.UI/DasBlog.Web.csproj @@ -22,6 +22,7 @@ +
diff --git a/source/DasBlog.Web.UI/Services/LoggingAgent.cs b/source/DasBlog.Web.UI/Services/LoggingAgent.cs new file mode 100644 index 00000000..9e8daa31 --- /dev/null +++ b/source/DasBlog.Web.UI/Services/LoggingAgent.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using DasBlog.Services; +using DasBlog.Services.ActivityLogs; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using Quartz.Util; + +namespace DasBlog.Web.Services +{ + public class LoggingAgent + { + private readonly ILogger logger; + private readonly RequestDelegate _next; + + public LoggingAgent(RequestDelegate next, ILogger logger) + { + _next = next; + this.logger = logger; + } + + public async Task Invoke(HttpContext context) + { + try + { + if (!context.Request.Headers["User-Agent"].ToString().IsNullOrWhiteSpace()) + { + logger.LogInformation(new EventDataItem(EventCodes.HttpUserAgent, null, context.Request.Headers["User-Agent"].ToString())); + } + + if (!context.Request.Headers["Referrer"].ToString().IsNullOrWhiteSpace()) + { + logger.LogInformation(new EventDataItem(EventCodes.HttpReferrer, null, context.Request.Headers["Referrer"].ToString())); + } + + if (!context.Request.HttpContext.Connection.RemoteIpAddress.ToString().IsNullOrWhiteSpace()) + { + logger.LogInformation(new EventDataItem(EventCodes.HttpReferrer, null, context.Request.HttpContext.Connection.RemoteIpAddress.ToString())); + } + } + catch (Exception ex) + { + logger.LogError(new EventDataItem(EventCodes.Error, null, string.Format("Logging Agent Exception:{0}", ex.Message))); + } + + await _next.Invoke(context); + } + } + + public static class MiddlewareExtensions + { + public static IApplicationBuilder UseLoggingAgent(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + } + + +} diff --git a/source/DasBlog.Web.UI/Settings/DasBlogSettings.cs b/source/DasBlog.Web.UI/Settings/DasBlogSettings.cs index 54b22ff2..88089d04 100644 --- a/source/DasBlog.Web.UI/Settings/DasBlogSettings.cs +++ b/source/DasBlog.Web.UI/Settings/DasBlogSettings.cs @@ -16,6 +16,7 @@ using System.Linq; using newtelligence.DasBlog.Runtime; using DasBlog.Services.FileManagement; +using System.Net.Mail; namespace DasBlog.Web.Settings { @@ -78,36 +79,16 @@ public string GetBaseUrl() return new Uri(SiteConfiguration.Root).AbsoluteUri; } - public static string GetBaseUrl(string root) - { - return new Uri(root).AbsoluteUri; - } - public string RelativeToRoot(string relative) { return new Uri(new Uri(SiteConfiguration.Root), relative).AbsoluteUri; } - public static string RelativeToRoot(string relative, string root) - { - return new Uri(new Uri(root), relative).AbsoluteUri; - } - /// - /// sticks root on the front of the entry id - /// - /// typically a guid - /// e.g. http://localhost:50432/ - /// public string GetPermaLinkUrl(string entryId) { return RelativeToRoot("post/" + entryId); } - public static string GetPermaLinkUrl(string entryId, string root) - { - return RelativeToRoot("post/" + entryId, root); - } - public string GetCommentViewUrl(string entryId) { return RelativeToRoot(entryId) + $"/comments#{Constants.CommentsStartId}"; @@ -173,28 +154,11 @@ public DateTimeZone GetConfiguredTimeZone() } } - public static DateTimeZone GetConfiguredTimeZone(bool adjustDisplayTimeZone, decimal displayTimeZoneIndex) - { - if (adjustDisplayTimeZone) - { - return DateTimeZone.ForOffset(Offset.FromSeconds((int)displayTimeZoneIndex * 3600)); - } - else - { - return DateTimeZone.Utc; - } - } - public DateTime GetContentLookAhead() { return DateTime.UtcNow.AddDays(SiteConfiguration.ContentLookaheadDays); } - public static DateTime GetContentLookAhead(int contentLookAheadDays) - { - return DateTime.UtcNow.AddDays(contentLookAheadDays); - } - public string FilterHtml(string input) { if (SiteConfiguration.ValidCommentTags == null || SiteConfiguration.ValidCommentTags[0].Tag.Count(s => s.Allowed == true) == 0) @@ -253,16 +217,6 @@ public bool AreCommentsPermitted(DateTime blogpostdate) return (DateTime.UtcNow.AddDays(-1 * SiteConfiguration.DaysCommentsAllowed) < blogpostdate); } - /// - /// sticks root on the front of the feeds url - /// - /// e.g. http://localhost:50432/ - /// e.g. http://localhost:50432;feed/rsd - public static string GetRsdUrl(string root) - { - return RelativeToRoot("feed/rsd", root); - } - public string GetPermaTitle(string titleurl) { var titlePermalink = titleurl.Trim(); @@ -306,5 +260,12 @@ public bool IsAdmin(string gravatarhashid) { return (Utils.GetGravatarHash(SecurityConfiguration.Users.First().EmailAddress) == gravatarhashid); } + + public SendMailInfo GetMailInfo(MailMessage emailmessage) + { + return new SendMailInfo(emailmessage, SiteConfiguration.SmtpServer, + SiteConfiguration.EnableSmtpAuthentication, SiteConfiguration.UseSSLForSMTP, + SiteConfiguration.SmtpUserName, SiteConfiguration.SmtpPassword, SiteConfiguration.SmtpPort); + } } } diff --git a/source/DasBlog.Web.UI/Startup.cs b/source/DasBlog.Web.UI/Startup.cs index 490d771b..4a5678c2 100644 --- a/source/DasBlog.Web.UI/Startup.cs +++ b/source/DasBlog.Web.UI/Startup.cs @@ -20,9 +20,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; -using Microsoft.Extensions.Options; using Microsoft.Extensions.Hosting; -using IHostingEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment; using System; using System.IO; using System.Linq; @@ -36,6 +34,8 @@ using Microsoft.AspNetCore.HttpOverrides; using DasBlog.Services.FileManagement.Interfaces; using Microsoft.Extensions.Logging; +using Quartz; +using DasBlog.Services.Scheduler; namespace DasBlog.Web { @@ -52,8 +52,6 @@ public class Startup private readonly string BinariesUrlRelativePath; private readonly IWebHostEnvironment hostingEnvironment; - - public static IServiceCollection DasBlogServices { get; private set; } public IConfiguration Configuration { get; } @@ -228,7 +226,45 @@ public void ConfigureServices(IServiceCollection services) .AddControllersWithViews() .AddRazorRuntimeCompilation(); - DasBlogServices = services; + services.AddQuartz(q => + { + q.SchedulerId = "Scheduler-Core"; + + q.UseMicrosoftDependencyInjectionJobFactory(options => + { + // if we don't have the job in DI, allow fallback to configure via default constructor + options.AllowDefaultConstructor = true; + }); + + q.UseSimpleTypeLoader(); + q.UseInMemoryStore(); + q.UseDefaultThreadPool(tp => + { + tp.MaxConcurrency = 10; + }); + + var jobKey = new JobKey("key1", "main-group"); + + q.AddJob(j => j + .StoreDurably() + .WithIdentity(jobKey) + .WithDescription("Site report job") + ); + + q.AddTrigger(t => t + .WithIdentity("Simple Trigger") + .ForJob(jobKey) + .StartNow() + .WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(23, 45)) + .WithDescription("my awesome simple trigger") + + ); + }); + + services.AddQuartzServer(options => + { + options.WaitForJobsToComplete = true; + }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -293,6 +329,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IDasBlog app.UseRouting(); app.UseAuthorization(); + app.UseLoggingAgent(); + app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/healthcheck"); diff --git a/source/DasBlog.Web.UI/appsettings.json b/source/DasBlog.Web.UI/appsettings.json index 0ace1c48..d1e26e76 100644 --- a/source/DasBlog.Web.UI/appsettings.json +++ b/source/DasBlog.Web.UI/appsettings.json @@ -3,7 +3,7 @@ "IncludeScopes": false, "LogLevel": { "Microsoft": "Error", - "DasBlog": "Error" + "DasBlog": "Information" } } } diff --git a/source/newtelligence.DasBlog.Runtime/BlogDataService.cs b/source/newtelligence.DasBlog.Runtime/BlogDataService.cs index 207d5419..d5dddc19 100644 --- a/source/newtelligence.DasBlog.Runtime/BlogDataService.cs +++ b/source/newtelligence.DasBlog.Runtime/BlogDataService.cs @@ -120,7 +120,7 @@ protected string UserAgent get { string version = GetType().Assembly.GetName().Version.ToString(); - return "newtelligence dasBlog/" + version; + return "dasBlog Core/" + version; } } @@ -319,58 +319,7 @@ DayExtra IBlogDataService.GetDayExtra(DateTime date) return InternalGetDayExtra(date); } -/* - protected void PingWeblogsWorker(object argument) - { - WeblogUpdatePingInfo weblogInfo = argument as WeblogUpdatePingInfo; - foreach (PingService pingService in weblogInfo.PingServices) - { - try - { - if (pingService.PingApi == PingService.PingApiType.Basic) - { - WeblogUpdatesClientProxy updates = new WeblogUpdatesClientProxy(pingService.Endpoint); - WeblogUpdatesReply reply = updates.Ping(weblogInfo.BlogName, weblogInfo.BlogUrl); - if (reply.flerror) - { - ErrorTrace.Trace(TraceLevel.Error, String.Format("Notifying {0}: {1}", pingService.Name, reply.message)); - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.PingWeblogsError, reply.message, weblogInfo.BlogUrl, pingService.Endpoint, pingService.Name)); - } - } - } - else if (pingService.PingApi == PingService.PingApiType.Extended) - { - ExtendedWeblogUpdatesClientProxy updates = new ExtendedWeblogUpdatesClientProxy(pingService.Endpoint); - WeblogUpdatesReply reply = updates.ExtendedPing(weblogInfo.BlogName, weblogInfo.BlogUrl, weblogInfo.CheckUrl, weblogInfo.RssUrl); - if (reply.flerror) - { - ErrorTrace.Trace(TraceLevel.Error, String.Format("Notifying {0}: {1}", pingService.Name, reply.message)); - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.PingWeblogsError, reply.message, weblogInfo.BlogUrl, pingService.Endpoint, pingService.Name)); - } - } - } - } - catch (Exception e) - { - ErrorTrace.Trace(TraceLevel.Error, e); - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.Error, - e.ToString().Replace("\n", "
"), - "PingWeblogsWorker, pinging " + pingService.Name)); - } - } - } - } -*/ protected class PingbackJob { @@ -384,142 +333,12 @@ internal PingbackJob(PingbackInfo info, Entry entry) } } -/* - protected void Pingback(string sourceUri, string pingbackService, string pingbackTarget, string entryTitle) - { - try - { - if (pingbackService != null && pingbackTarget != null) - { - PingbackClientProxy client = new PingbackClientProxy(); - client.UserAgent = this.UserAgent; - client.Url = pingbackService; - client.ping(sourceUri, pingbackTarget); - this.loggingService.AddEvent( - new EventDataItem( - EventCodes.PingbackSent, - entryTitle, - sourceUri, - pingbackTarget)); - } - } - catch (XmlRpcFaultException xmlFault) - { - ErrorTrace.Trace(TraceLevel.Error, xmlFault); - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.PingbackServerError, - String.Format("{0}: {1}", xmlFault.FaultCode, xmlFault.FaultString), - sourceUri + "," + pingbackTarget)); - } - } - catch (Exception e) - { - ErrorTrace.Trace(TraceLevel.Error, e); - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.PingbackServerError, - e.ToString().Replace("\n", "
"), - sourceUri + "," + pingbackTarget)); - } - } - } -*/ private static readonly Regex anchors = new Regex("href\\s*=\\s*(?:(?:\\\"(?[^\\\"]*)\\\")|(?[^\\s]* ))", RegexOptions.Compiled); private static readonly Regex pingbackRegex = new Regex("", RegexOptions.IgnoreCase | RegexOptions.Compiled); -/* - protected void PingbackWorker(object argument) - { - PingbackJob job = argument as PingbackJob; - if (job.entry.Content != null && - job.entry.Content.Length > 0) - { - - foreach (Match match in anchors.Matches(job.entry.Content)) - { - string url = match.Groups["url"].Value; - - if (url.StartsWith("http")) - { // don't pass in a url withouth http into Uri constructor - try - { - Uri externalUri = new Uri(url); - - if (externalUri.Scheme == Uri.UriSchemeHttp) - { - // we're auto-detecting pingbacks and while we do that - // we send a trackback in hope that the server may understand - // that already. We're appending to the target URL and - // therefore shouldn't interfere with the server logic in case - // the identifiers collide with those the server is using. - - HttpWebRequest webRequest = WebRequest.Create(externalUri) as HttpWebRequest; - webRequest.Method = "GET"; - webRequest.UserAgent = this.UserAgent; - - HttpWebResponse response = webRequest.GetResponse() as HttpWebResponse; - - // now we want to get the page contents of the target body - string requestBody = null; - using (StreamReader requestReader = new StreamReader(response.GetResponseStream())) - { - requestBody = requestReader.ReadToEnd(); - } - response.Close(); - - // we will try a trackback first before a pingback - // we need to auto discover the trackback url - // http://www.movabletype.org/docs/mttrackback.html - - string trackbackUrl = GetTrackbackLink(requestBody, externalUri.AbsoluteUri); - if (trackbackUrl != null) - { - TrackbackInfo info = new TrackbackInfo(trackbackUrl, job.info.SourceUrl, job.info.SourceTitle, job.info.SourceExcerpt, job.info.SourceBlogName); - TrackbackWorker(new TrackbackJob(info, job.entry)); - } - - // first we try and get the X-Pingback HTTP header - // http://www.hixie.ch/specs/pingback/pingback - string pingbackService = response.GetResponseHeader("X-Pingback"); - - // if we don't get the header - // try and autodetect the auto pingback info - if (pingbackService == null || pingbackService.Length == 0) - { - string[] split = pingbackRegex.Split(requestBody); - - if (split.Length == 1) - pingbackService = split[0]; - } - - if (pingbackService != null && pingbackService.Length > 0) - { - Pingback(job.info.SourceUrl, pingbackService, url, job.entry.Title); - } - } - } - catch (Exception e) - { - ErrorTrace.Trace(TraceLevel.Error, e); - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.Error, - e.ToString().Replace("\n", "
"), - "PingbackWorker, auto-discovery of: " + url)); - } - } - } - } - } - } -*/ private class TrackbackJob { @@ -633,191 +452,6 @@ internal CrosspostJob(object info, Entry entry, IBlogDataService dataService) } -/* - protected void HandleCrosspost(CrosspostInfo ci, Entry entry) - { - try - { - BloggerAPIClientProxy proxy = new BloggerAPIClientProxy(); - UriBuilder uriBuilder = new UriBuilder("http", ci.Site.HostName, ci.Site.Port, ci.Site.Endpoint); - proxy.Url = uriBuilder.ToString(); - proxy.UserAgent = this.UserAgent; - - if (ci.IsAlreadyPosted) - { - try - { - if (ci.Site.ApiType == "metaweblog") - { - mwPost existingPost = new mwPost(); - existingPost.link = ""; - existingPost.permalink = ""; - existingPost.categories = ci.Categories.Split(';'); - existingPost.postid = ci.TargetEntryId; - existingPost.dateCreated = entry.CreatedLocalTime; - existingPost.title = entry.Title; - existingPost.description = entry.Content + ci.GetTrackingSnippet(entry.EntryId); - - proxy.metaweblog_editPost(ci.TargetEntryId, ci.Site.Username, ci.Site.Password, existingPost, true); - - Crosspost cp = new Crosspost(); - cp.TargetEntryId = ci.TargetEntryId; - cp.ProfileName = ci.Site.ProfileName; - cp.Categories = ci.Categories; - entry.Crossposts.Add(cp); - - } - else if (ci.Site.ApiType == "blogger") - { - proxy.blogger_editPost("", ci.TargetEntryId, ci.Site.Username, ci.Site.Password, entry.Content + ci.GetTrackingSnippet(entry.EntryId), true); - - Crosspost cp = new Crosspost(); - cp.TargetEntryId = ci.TargetEntryId; - cp.ProfileName = ci.Site.ProfileName; - entry.Crossposts.Add(cp); - } - - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.CrosspostChanged, ci.Site.HostName, null)); - } - - } - catch (XmlRpcFaultException xrfe) - { - ErrorTrace.Trace(TraceLevel.Error, xrfe); - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.Error, - xrfe.Message, - String.Format("Updating cross-post entry {0} on {1}; Failed with server-fault code, {2} \"{3}\"", ci.TargetEntryId, ci.Site.ProfileName, xrfe.FaultCode, xrfe.FaultString))); - } - } - catch (Exception e) - { - ErrorTrace.Trace(TraceLevel.Error, e); - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.Error, - e.ToString().Replace("\n", "
"), - String.Format("Updating cross-post entry {0} on {1}", ci.TargetEntryId, ci.Site.ProfileName))); - } - } - } - else - { - try - { - - if (ci.Site.ApiType == "metaweblog") - { - mwPost newPost = new mwPost(); - newPost.link = ""; - newPost.permalink = ""; - newPost.postid = ""; - newPost.categories = ci.Categories.Split(';'); - newPost.dateCreated = entry.CreatedLocalTime; - newPost.description = entry.Content + ci.GetTrackingSnippet(entry.EntryId); - newPost.title = entry.Title; - newPost.postid = proxy.metaweblog_newPost(ci.Site.BlogId, - ci.Site.Username, - ci.Site.Password, - newPost, true); - Crosspost cp = new Crosspost(); - cp.TargetEntryId = newPost.postid; - cp.ProfileName = ci.Site.ProfileName; - cp.Categories = ci.Categories; - entry.Crossposts.Add(cp); - } - else if (ci.Site.ApiType == "blogger") - { - Crosspost cp = new Crosspost(); - cp.TargetEntryId = proxy.blogger_newPost("", ci.Site.BlogId, ci.Site.Username, ci.Site.Password, entry.Content + ci.GetTrackingSnippet(entry.EntryId), true); - cp.ProfileName = ci.Site.ProfileName; - entry.Crossposts.Add(cp); - } - - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.CrosspostAdded, ci.Site.HostName, null)); - } - } - catch (XmlRpcFaultException xrfe) - { - ErrorTrace.Trace(TraceLevel.Error, xrfe); - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.Error, - xrfe.Message, - String.Format("Adding cross-post entry to {0}; Failed with server-fault code, {1} \"{2}\"", ci.Site.ProfileName, xrfe.FaultCode, xrfe.FaultString))); - } - } - catch (Exception e) - { - ErrorTrace.Trace(TraceLevel.Error, e); - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.Error, - e.ToString().Replace("\n", "
"), - String.Format("Adding cross-post entry to {0}", ci.Site.ProfileName))); - } - } - } - } - catch (Exception e) - { - ErrorTrace.Trace(TraceLevel.Error, e); - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.Error, - e.ToString().Replace("\n", "
"), - String.Format("HandleCrosspost to {0}", ci.Site.ProfileName))); - } - } - - } - - protected void CrosspostWorker(object argument) - { - CrosspostJob job = argument as CrosspostJob; - try - { - if (job.info is CrosspostInfoCollection) - { - foreach (CrosspostInfo ci in job.info as CrosspostInfoCollection) - { - HandleCrosspost(ci, job.entry); - } - } - else if (job.info is CrosspostInfo) - { - HandleCrosspost(job.info as CrosspostInfo, job.entry); - } - - job.dataService.SaveEntry(job.entry); - - } - catch (Exception e) - { - ErrorTrace.Trace(TraceLevel.Error, e); - if (loggingService != null) - { - loggingService.AddEvent( - new EventDataItem(EventCodes.Error, - e.ToString().Replace("\n", "
"), - "CrosspostWorker")); - } - } - } -*/ - protected Entry InternalGetEntry(string entryId) { Entry entryResult = null; @@ -869,17 +503,6 @@ Entry IBlogDataService.GetEntry(string entryId) return InternalGetEntry(entryId); } - // /// - // /// Returns the Entry for a given entryId. - // /// - // /// - // /// - // string IBlogDataService.GetEntryTitle( string entryId ) - // { - // EntryIdCache ecache = GetEntryIdCache(); - // string title = ecache.GetTitleFromEntryId(entryId); - // return title; - // } /// /// Returns a copy of the Entry for a given entryId. You must Save the Entry for changes to be