Fixing scheduling of blog posts from Live Writer

work item: 17041

--HG--
branch : dev
This commit is contained in:
Nathan Heskew
2010-12-14 15:51:48 -08:00
parent 6bd7e40958
commit 19846507dc
3 changed files with 207 additions and 10 deletions

View File

@@ -70,7 +70,8 @@ namespace Orchard.Blogs.Services {
Convert.ToString(context.Request.Params[0].Value), Convert.ToString(context.Request.Params[0].Value),
Convert.ToString(context.Request.Params[1].Value), Convert.ToString(context.Request.Params[1].Value),
Convert.ToString(context.Request.Params[2].Value), Convert.ToString(context.Request.Params[2].Value),
Convert.ToInt32(context.Request.Params[3].Value)); Convert.ToInt32(context.Request.Params[3].Value),
context._drivers);
context.Response = new XRpcMethodResponse().Add(result); context.Response = new XRpcMethodResponse().Add(result);
} }
@@ -147,7 +148,8 @@ namespace Orchard.Blogs.Services {
string blogId, string blogId,
string userName, string userName,
string password, string password,
int numberOfPosts) { int numberOfPosts,
IEnumerable<IXmlRpcDriver> drivers) {
IUser user = ValidateUser(userName, password); IUser user = ValidateUser(userName, password);
@@ -161,7 +163,12 @@ namespace Orchard.Blogs.Services {
var array = new XRpcArray(); var array = new XRpcArray();
foreach (var blogPost in _blogPostService.Get(blog, 0, numberOfPosts, VersionOptions.Latest)) { foreach (var blogPost in _blogPostService.Get(blog, 0, numberOfPosts, VersionOptions.Latest)) {
array.Add(CreateBlogStruct(blogPost, urlHelper)); var postStruct = CreateBlogStruct(blogPost, urlHelper);
foreach (var driver in drivers)
driver.Process(postStruct);
array.Add(postStruct);
} }
return array; return array;
} }
@@ -210,7 +217,8 @@ namespace Orchard.Blogs.Services {
_contentManager.Create(blogPost.ContentItem, VersionOptions.Draft); _contentManager.Create(blogPost.ContentItem, VersionOptions.Draft);
if (publish) var publishedUtc = content.Optional<DateTime?>("dateCreated");
if (publish && (publishedUtc == null || publishedUtc <= DateTime.UtcNow))
_blogPostService.Publish(blogPost); _blogPostService.Publish(blogPost);
foreach (var driver in drivers) foreach (var driver in drivers)
@@ -253,11 +261,21 @@ namespace Orchard.Blogs.Services {
var description = content.Optional<string>("description"); var description = content.Optional<string>("description");
var slug = content.Optional<string>("wp_slug"); var slug = content.Optional<string>("wp_slug");
blogPost.Title = title; // BodyPart
blogPost.Slug = slug; if (blogPost.Is<BodyPart>()) {
blogPost.Text = description; blogPost.As<BodyPart>().Text = description;
}
if (publish) //RoutePart
if (blogPost.Is<RoutePart>()) {
blogPost.As<RoutePart>().Title = title;
blogPost.As<RoutePart>().Slug = slug;
_routableService.FillSlugFromTitle(blogPost.As<RoutePart>());
blogPost.As<RoutePart>().Path = blogPost.As<RoutePart>().GetPathWithSlug(blogPost.As<RoutePart>().Slug);
}
var publishedUtc = content.Optional<DateTime?>("dateCreated");
if (publish && (publishedUtc == null || publishedUtc <= DateTime.UtcNow))
_blogPostService.Publish(blogPost); _blogPostService.Publish(blogPost);
foreach (var driver in drivers) foreach (var driver in drivers)
@@ -292,14 +310,20 @@ namespace Orchard.Blogs.Services {
private static XRpcStruct CreateBlogStruct(BlogPostPart blogPostPart, UrlHelper urlHelper) { private static XRpcStruct CreateBlogStruct(BlogPostPart blogPostPart, UrlHelper urlHelper) {
var url = urlHelper.AbsoluteAction(() => urlHelper.BlogPost(blogPostPart)); var url = urlHelper.AbsoluteAction(() => urlHelper.BlogPost(blogPostPart));
return new XRpcStruct() var blogStruct = new XRpcStruct()
.Set("postid", blogPostPart.Id) .Set("postid", blogPostPart.Id)
.Set("dateCreated", blogPostPart.PublishedUtc)
.Set("title", blogPostPart.Title) .Set("title", blogPostPart.Title)
.Set("wp_slug", blogPostPart.Slug) .Set("wp_slug", blogPostPart.Slug)
.Set("description", blogPostPart.Text) .Set("description", blogPostPart.Text)
.Set("link", url) .Set("link", url)
.Set("permaLink", url); .Set("permaLink", url);
if (blogPostPart.PublishedUtc != null) {
blogStruct.Set("dateCreated", blogPostPart.PublishedUtc);
blogStruct.Set("date_created_gmt", blogPostPart.PublishedUtc);
}
return blogStruct;
} }
} }
} }

View File

@@ -44,6 +44,8 @@
<HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath> <HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Web" /> <Reference Include="System.Web" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Drivers\PublishLaterPartDriver.cs" /> <Compile Include="Drivers\PublishLaterPartDriver.cs" />
@@ -59,6 +61,7 @@
<Compile Include="Services\IPublishLaterService.cs" /> <Compile Include="Services\IPublishLaterService.cs" />
<Compile Include="Services\PublishingTaskManager.cs" /> <Compile Include="Services\PublishingTaskManager.cs" />
<Compile Include="Services\PublishLaterService.cs" /> <Compile Include="Services\PublishLaterService.cs" />
<Compile Include="Services\XmlRpcHandler.cs" />
<Compile Include="ViewModels\PublishLaterViewModel.cs" /> <Compile Include="ViewModels\PublishLaterViewModel.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -0,0 +1,170 @@
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using Orchard.ContentManagement;
using Orchard.Core.Contents;
using Orchard.Core.XmlRpc;
using Orchard.Core.XmlRpc.Models;
using Orchard.Localization;
using Orchard.PublishLater.Models;
using Orchard.Security;
using Orchard.Tasks.Scheduling;
namespace Orchard.PublishLater.Services {
public class XmlRpcHandler : IXmlRpcHandler {
private readonly IContentManager _contentManager;
private readonly IPublishingTaskManager _publishingTaskManager;
private readonly IMembershipService _membershipService;
private readonly IAuthorizationService _authorizationService;
public XmlRpcHandler(IContentManager contentManager,
IPublishingTaskManager publishingTaskManager,
IMembershipService membershipService,
IAuthorizationService authorizationService) {
_contentManager = contentManager;
_publishingTaskManager = publishingTaskManager;
_membershipService = membershipService;
_authorizationService = authorizationService;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
public void SetCapabilities(XElement options) {
const string manifestUri = "http://schemas.microsoft.com/wlw/manifest/weblog";
options.SetElementValue(XName.Get("supportsCustomDate", manifestUri), "Yes");
}
public void Process(XmlRpcContext context) {
switch (context.Request.MethodName) {
case "metaWeblog.newPost":
MetaWeblogSetCustomPublishedDate(
GetId(context.Response),
Convert.ToString(context.Request.Params[0].Value),
Convert.ToString(context.Request.Params[1].Value),
Convert.ToString(context.Request.Params[2].Value),
(XRpcStruct)context.Request.Params[3].Value,
Convert.ToBoolean(context.Request.Params[4].Value),
context._drivers);
break;
case "metaWeblog.editPost":
MetaWeblogSetCustomPublishedDate(
GetId(context.Response),
Convert.ToString(context.Request.Params[0].Value),
Convert.ToString(context.Request.Params[1].Value),
Convert.ToString(context.Request.Params[2].Value),
(XRpcStruct)context.Request.Params[3].Value,
Convert.ToBoolean(context.Request.Params[4].Value),
context._drivers);
break;
case "metaWeblog.getPost":
MetaWeblogGetCustomPublishedDate(
GetPost(context.Response),
Convert.ToInt32(context.Request.Params[0].Value),
Convert.ToString(context.Request.Params[1].Value),
Convert.ToString(context.Request.Params[2].Value),
context._drivers);
break;
case "metaWeblog.getRecentPosts":
MetaWeblogGetCustomPublishedDate(
GetPost(context.Response),
Convert.ToInt32(context.Request.Params[0].Value),
Convert.ToString(context.Request.Params[1].Value),
Convert.ToString(context.Request.Params[2].Value),
context._drivers);
break;
}
}
private void MetaWeblogGetCustomPublishedDate(XRpcStruct postStruct, int itemId, string userName, string password, ICollection<IXmlRpcDriver> drivers) {
if (itemId < 1)
return;
var driver = new XmlRpcDriver(item => {
var post = item as XRpcStruct;
if (post == null)
return;
var postId = post.Optional<int>("postid");
var contentItem = _contentManager.Get(postId, VersionOptions.Latest);
if (contentItem == null)
return;
var publishedUtc = contentItem.As<PublishLaterPart>().ScheduledPublishUtc.Value;
if (publishedUtc == null || publishedUtc <= DateTime.UtcNow)
return;
post.Set("dateCreated", publishedUtc);
post.Set("date_created_gmt", publishedUtc);
});
if (postStruct != null)
driver.Process(postStruct);
else
drivers.Add(driver);
}
private void MetaWeblogSetCustomPublishedDate(int contentItemId, string appKey, string userName, string password, XRpcStruct content, bool publish, ICollection<IXmlRpcDriver> drivers) {
var user = ValidateUser(userName, password);
if (user == null)
return;
var publishedUtc = content.Optional<DateTime?>("dateCreated");
if (publishedUtc == null || publishedUtc <= DateTime.UtcNow) // only post-dating/scheduling of content with the PublishLaterPart
return;
var driver = new XmlRpcDriver(item => {
if (!(item is int))
return;
var id = (int)item;
var contentItem = _contentManager.Get(id, VersionOptions.Latest);
if (contentItem == null || !contentItem.Is<PublishLaterPart>())
return;
_authorizationService.CheckAccess(Permissions.PublishOthersContent, user, null);
contentItem.As<PublishLaterPart>().ScheduledPublishUtc.Value = publishedUtc;
_publishingTaskManager.Publish(contentItem, (DateTime)publishedUtc);
});
if (contentItemId > 0)
driver.Process(contentItemId);
else
drivers.Add(driver);
}
private static XRpcStruct GetPost(XRpcMethodResponse response) {
return response != null && response.Params.Count == 1 && response.Params[0].Value is XRpcStruct
? response.Params[0].Value as XRpcStruct
: null;
}
private static int GetId(XRpcMethodResponse response) {
return response != null && response.Params.Count == 1 && response.Params[0].Value is int
? Convert.ToInt32(response.Params[0].Value)
: 0;
}
private IUser ValidateUser(string userName, string password) {
IUser user = _membershipService.ValidateUser(userName, password);
if (user == null) {
throw new OrchardCoreException(T("The username or e-mail or password provided is incorrect."));
}
return user;
}
public class XmlRpcDriver : IXmlRpcDriver {
private readonly Action<object> _process;
public XmlRpcDriver(Action<object> process) {
_process = process;
}
public void Process(object item) {
_process(item);
}
}
}
}