diff --git a/AzurePackage.proj b/AzurePackage.proj index a5bc7ccfa..9ea83c86e 100644 --- a/AzurePackage.proj +++ b/AzurePackage.proj @@ -72,8 +72,6 @@ - - @@ -113,24 +111,6 @@ XPath="/log4net/root/priority/@value" Value="ERROR" /> - - - - - - - - - - - - diff --git a/ClickToRunAzureInDevFabric.cmd b/ClickToRunAzureInDevFabric.cmd deleted file mode 100644 index c0a35a30e..000000000 --- a/ClickToRunAzureInDevFabric.cmd +++ /dev/null @@ -1,5 +0,0 @@ -SET CDIR = %CD% -call "%ProgramFiles%\Windows Azure SDK\v1.2\bin\setenv.cmd" -csrun /devstore -csrun /run:"%CDIR %\build\Compile\Orchard.Azure.CloudService.csx";"%CDIR %\src\Orchard.Azure\Orchard.Azure.CloudService\ServiceConfiguration.cscfg" /launchbrowser -pause \ No newline at end of file diff --git a/src/Orchard.Azure.Tests/App.config b/src/Orchard.Azure.Tests/App.config index dcb9cb146..41aa17680 100644 --- a/src/Orchard.Azure.Tests/App.config +++ b/src/Orchard.Azure.Tests/App.config @@ -1,7 +1,7 @@ - + diff --git a/src/Orchard.Azure.Tests/Orchard.Azure.Tests.csproj b/src/Orchard.Azure.Tests/Orchard.Azure.Tests.csproj index ecdce0f39..355147332 100644 --- a/src/Orchard.Azure.Tests/Orchard.Azure.Tests.csproj +++ b/src/Orchard.Azure.Tests/Orchard.Azure.Tests.csproj @@ -55,7 +55,7 @@ - + False ..\..\lib\moq\Moq.dll diff --git a/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceConfiguration.cscfg b/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceConfiguration.cscfg index 0e71f7efb..9600d5e76 100644 --- a/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceConfiguration.cscfg +++ b/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceConfiguration.cscfg @@ -1,5 +1,5 @@ - + diff --git a/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef b/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef index 0cc371c69..3503cc02c 100644 --- a/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef +++ b/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef @@ -1,11 +1,18 @@  + + + + + + + - + - + \ No newline at end of file diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Global.asax.cs b/src/Orchard.Azure/Orchard.Azure.Web/Global.asax.cs index 2b3cdbad3..bd2b37c44 100644 --- a/src/Orchard.Azure/Orchard.Azure.Web/Global.asax.cs +++ b/src/Orchard.Azure/Orchard.Azure.Web/Global.asax.cs @@ -1,7 +1,10 @@ -using System.Web; +using System.Linq; +using System.Web; using System.Web.Mvc; using System.Web.Routing; using Autofac; +using Microsoft.WindowsAzure; +using Microsoft.WindowsAzure.ServiceRuntime; using Orchard.Environment; namespace Orchard.Azure.Web { @@ -16,6 +19,21 @@ namespace Orchard.Azure.Web { } protected void Application_Start() { + CloudStorageAccount.SetConfigurationSettingPublisher( + (configName, configSetter) => + configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)) + ); + + // For information on handling configuration changes + // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357. + RoleEnvironment.Changing += (sender, e) => { + // If a configuration setting is changing + if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange)) { + // Set e.Cancel to true to restart this role instance + e.Cancel = true; + } + }; + RegisterRoutes(RouteTable.Routes); _host = OrchardStarter.CreateHost(MvcSingletons); diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj b/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj index 31d043fba..0550e42a9 100644 --- a/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj +++ b/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj @@ -58,7 +58,7 @@ False - + ..\..\..\lib\fluentnhibernate\NHibernate.ByteCode.Castle.dll @@ -144,7 +144,6 @@ Global.asax - diff --git a/src/Orchard.Azure/Orchard.Azure.Web/WebRole.cs b/src/Orchard.Azure/Orchard.Azure.Web/WebRole.cs deleted file mode 100644 index 4db62c516..000000000 --- a/src/Orchard.Azure/Orchard.Azure.Web/WebRole.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Linq; -using Microsoft.WindowsAzure; -using Microsoft.WindowsAzure.ServiceRuntime; - -namespace Orchard.Azure.Web { - public class WebRole : RoleEntryPoint { - public override bool OnStart() { - CloudStorageAccount.SetConfigurationSettingPublisher( - (configName, configSetter) => - configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)) - ); - - // For information on handling configuration changes - // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357. - RoleEnvironment.Changing += RoleEnvironmentChanging; - - return base.OnStart(); - } - - private static void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e) { - // If a configuration setting is changing - if ( e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange) ) { - // Set e.Cancel to true to restart this role instance - e.Cancel = true; - } - } - } -} diff --git a/src/Orchard.Azure/Orchard.Azure.csproj b/src/Orchard.Azure/Orchard.Azure.csproj index b70945429..01dd0d140 100644 --- a/src/Orchard.Azure/Orchard.Azure.csproj +++ b/src/Orchard.Azure/Orchard.Azure.csproj @@ -54,7 +54,7 @@ - + 3.5 diff --git a/src/Orchard.Web/Core/Common/Services/XmlRpcHandler.cs b/src/Orchard.Web/Core/Common/Services/XmlRpcHandler.cs new file mode 100644 index 000000000..b4a9ff5b9 --- /dev/null +++ b/src/Orchard.Web/Core/Common/Services/XmlRpcHandler.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Xml.Linq; +using Orchard.ContentManagement; +using Orchard.Core.Common.Models; +using Orchard.Core.XmlRpc; +using Orchard.Core.XmlRpc.Models; + +namespace Orchard.Core.Common.Services { + public class XmlRpcHandler : IXmlRpcHandler { + private readonly IContentManager _contentManager; + + public XmlRpcHandler(IContentManager contentManager) { + _contentManager = contentManager; + } + + 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; + } + } + + private void MetaWeblogSetCustomPublishedDate(int contentItemId, string appKey, string userName, string password, XRpcStruct content, bool publish, ICollection drivers) { + if (!publish) + return; + + var publishedUtc = content.Optional("dateCreated"); + if (publishedUtc == null || publishedUtc > DateTime.UtcNow) // only pre-dating of content with the CommonPart + 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()) + return; + + contentItem.As().PublishedUtc = publishedUtc; + }); + + if (contentItemId > 0) + driver.Process(contentItemId); + else + drivers.Add(driver); + } + + 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; + } + + public class XmlRpcDriver : IXmlRpcDriver { + private readonly Action _process; + + public XmlRpcDriver(Action process) { + _process = process; + } + + public void Process(object item) { + _process(item); + } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Orchard.Core.csproj b/src/Orchard.Web/Core/Orchard.Core.csproj index 67b970439..b59372d85 100644 --- a/src/Orchard.Web/Core/Orchard.Core.csproj +++ b/src/Orchard.Web/Core/Orchard.Core.csproj @@ -62,6 +62,7 @@ + diff --git a/src/Orchard.Web/Core/XmlRpc/Controllers/LiveWriterController.cs b/src/Orchard.Web/Core/XmlRpc/Controllers/LiveWriterController.cs index 439f883a7..4b3f0885a 100644 --- a/src/Orchard.Web/Core/XmlRpc/Controllers/LiveWriterController.cs +++ b/src/Orchard.Web/Core/XmlRpc/Controllers/LiveWriterController.cs @@ -27,7 +27,8 @@ namespace Orchard.Core.XmlRpc.Controllers { new XElement(XName.Get("clientType", ManifestUri), "Metaweblog"), new XElement(XName.Get("supportsKeywords", ManifestUri), "No"), new XElement(XName.Get("supportsCategories", ManifestUri), "No"), - new XElement(XName.Get("supportsFileUpload", ManifestUri), "No")); + new XElement(XName.Get("supportsFileUpload", ManifestUri), "No"), + new XElement(XName.Get("supportsCustomDate", ManifestUri), "No")); foreach (var handler in _xmlRpcHandlers) handler.SetCapabilities(options); diff --git a/src/Orchard.Web/Core/XmlRpc/Services/XmlRpcReader.cs b/src/Orchard.Web/Core/XmlRpc/Services/XmlRpcReader.cs index dd641f443..90fb19c95 100644 --- a/src/Orchard.Web/Core/XmlRpc/Services/XmlRpcReader.cs +++ b/src/Orchard.Web/Core/XmlRpc/Services/XmlRpcReader.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Xml.Linq; using Orchard.Core.XmlRpc.Models; @@ -23,7 +24,9 @@ namespace Orchard.Core.XmlRpc.Services { {"double", x=>new XRpcData { Value = (double)x }}, {"dateTime.iso8601", x=> { DateTime parsedDateTime; - if(!DateTime.TryParse(x.Value, out parsedDateTime)) { + // try parsing a "normal" datetime string then try what live writer gives us + if(!DateTime.TryParse(x.Value, out parsedDateTime) + && !DateTime.TryParseExact(x.Value, "yyyyMMddTHH:mm:ss", DateTimeFormatInfo.CurrentInfo, DateTimeStyles.None, out parsedDateTime)) { parsedDateTime = DateTime.Now; } return new XRpcData {Value = parsedDateTime}; diff --git a/src/Orchard.Web/Core/XmlRpc/Services/XmlRpcWriter.cs b/src/Orchard.Web/Core/XmlRpc/Services/XmlRpcWriter.cs index 0f1517054..8cd9d84de 100644 --- a/src/Orchard.Web/Core/XmlRpc/Services/XmlRpcWriter.cs +++ b/src/Orchard.Web/Core/XmlRpc/Services/XmlRpcWriter.cs @@ -18,8 +18,8 @@ namespace Orchard.Core.XmlRpc.Services { {typeof(bool), p=>new XElement("boolean", (bool)p.Value?"1":"0")}, {typeof(string), p=>new XElement("string", p.Value)}, {typeof(double), p=>new XElement("double", (double)p.Value)}, - {typeof(DateTime), p=>new XElement("dateTime.iso8601", ((DateTime)p.Value).ToString("o"))}, - {typeof(DateTime?), p=>new XElement("dateTime.iso8601", ((DateTime?)p.Value).Value.ToString("o"))}, + {typeof(DateTime), p=>new XElement("dateTime.iso8601", ((DateTime)p.Value).ToString("yyyyMMddTHH:mm:ssZ"))}, + {typeof(DateTime?), p=>new XElement("dateTime.iso8601", ((DateTime?)p.Value).Value.ToString("yyyyMMddTHH:mm:ssZ"))}, {typeof(byte[]), p=>new XElement("base64", Convert.ToBase64String((byte[])p.Value))}, {typeof(XRpcStruct), p=>Map((XRpcStruct)p.Value)}, {typeof(XRpcArray), p=>Map((XRpcArray)p.Value)}, diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogPostPartHandler.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogPostPartHandler.cs index 34878376a..281cc498f 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogPostPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogPostPartHandler.cs @@ -51,7 +51,7 @@ namespace Orchard.Blogs.Handlers { OnCreated((context, bp) => updateBlogPostCount(bp.BlogPart)); OnPublished((context, bp) => updateBlogPostCount(bp.BlogPart)); OnUnpublished((context, bp) => updateBlogPostCount(bp.BlogPart)); - OnVersioned((context, bp1, bp2) => updateBlogPostCount(bp2.BlogPart)); + OnVersioned((context, bp1, bp2) => updateBlogPostCount(bp1.BlogPart)); OnRemoved((context, bp) => updateBlogPostCount(bp.BlogPart)); OnRemoved( diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPostPart.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPostPart.cs index c6b81028d..1de49e1ec 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPostPart.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPostPart.cs @@ -51,33 +51,8 @@ namespace Orchard.Blogs.Models { } } - public DateTime? CreatedUtc { - get { return this.As().CreatedUtc; } - } - - public DateTime? ScheduledPublishUtc { get; set; } - - private string _scheduledPublishUtcDate; - - public string ScheduledPublishUtcDate - { - get { - return !HasPublished && !string.IsNullOrEmpty(_scheduledPublishUtcDate) || !ScheduledPublishUtc.HasValue - ? _scheduledPublishUtcDate - : ScheduledPublishUtc.Value.ToShortDateString(); - } - set { _scheduledPublishUtcDate = value; } - } - - private string _scheduledPublishUtcTime; - - public string ScheduledPublishUtcTime { - get { - return !HasPublished && !string.IsNullOrEmpty(_scheduledPublishUtcTime) || !ScheduledPublishUtc.HasValue - ? _scheduledPublishUtcTime - : ScheduledPublishUtc.Value.ToShortTimeString(); - } - set { _scheduledPublishUtcTime = value; } + public DateTime? PublishedUtc { + get { return this.As().PublishedUtc; } } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Services/XmlRpcHandler.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Services/XmlRpcHandler.cs index 01190a656..bf06b98ac 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Services/XmlRpcHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Services/XmlRpcHandler.cs @@ -70,7 +70,8 @@ namespace Orchard.Blogs.Services { Convert.ToString(context.Request.Params[0].Value), Convert.ToString(context.Request.Params[1].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); } @@ -147,7 +148,8 @@ namespace Orchard.Blogs.Services { string blogId, string userName, string password, - int numberOfPosts) { + int numberOfPosts, + IEnumerable drivers) { IUser user = ValidateUser(userName, password); @@ -161,7 +163,12 @@ namespace Orchard.Blogs.Services { var array = new XRpcArray(); 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; } @@ -210,7 +217,8 @@ namespace Orchard.Blogs.Services { _contentManager.Create(blogPost.ContentItem, VersionOptions.Draft); - if (publish) + var publishedUtc = content.Optional("dateCreated"); + if (publish && (publishedUtc == null || publishedUtc <= DateTime.UtcNow)) _blogPostService.Publish(blogPost); foreach (var driver in drivers) @@ -253,11 +261,21 @@ namespace Orchard.Blogs.Services { var description = content.Optional("description"); var slug = content.Optional("wp_slug"); - blogPost.Title = title; - blogPost.Slug = slug; - blogPost.Text = description; + // BodyPart + if (blogPost.Is()) { + blogPost.As().Text = description; + } - if (publish) + //RoutePart + if (blogPost.Is()) { + blogPost.As().Title = title; + blogPost.As().Slug = slug; + _routableService.FillSlugFromTitle(blogPost.As()); + blogPost.As().Path = blogPost.As().GetPathWithSlug(blogPost.As().Slug); + } + + var publishedUtc = content.Optional("dateCreated"); + if (publish && (publishedUtc == null || publishedUtc <= DateTime.UtcNow)) _blogPostService.Publish(blogPost); foreach (var driver in drivers) @@ -292,14 +310,20 @@ namespace Orchard.Blogs.Services { private static XRpcStruct CreateBlogStruct(BlogPostPart blogPostPart, UrlHelper urlHelper) { var url = urlHelper.AbsoluteAction(() => urlHelper.BlogPost(blogPostPart)); - return new XRpcStruct() + var blogStruct = new XRpcStruct() .Set("postid", blogPostPart.Id) - .Set("dateCreated", blogPostPart.CreatedUtc) .Set("title", blogPostPart.Title) .Set("wp_slug", blogPostPart.Slug) .Set("description", blogPostPart.Text) .Set("link", url) .Set("permaLink", url); + + if (blogPostPart.PublishedUtc != null) { + blogStruct.Set("dateCreated", blogPostPart.PublishedUtc); + blogStruct.Set("date_created_gmt", blogPostPart.PublishedUtc); + } + + return blogStruct; } } } diff --git a/src/Orchard.Web/Modules/Orchard.PublishLater/Orchard.PublishLater.csproj b/src/Orchard.Web/Modules/Orchard.PublishLater/Orchard.PublishLater.csproj index c0bdc79e1..c1fb4b84f 100644 --- a/src/Orchard.Web/Modules/Orchard.PublishLater/Orchard.PublishLater.csproj +++ b/src/Orchard.Web/Modules/Orchard.PublishLater/Orchard.PublishLater.csproj @@ -44,6 +44,8 @@ ..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll + + @@ -59,6 +61,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.PublishLater/Services/XmlRpcHandler.cs b/src/Orchard.Web/Modules/Orchard.PublishLater/Services/XmlRpcHandler.cs new file mode 100644 index 000000000..5b825e326 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.PublishLater/Services/XmlRpcHandler.cs @@ -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 drivers) { + if (itemId < 1) + return; + + var driver = new XmlRpcDriver(item => { + var post = item as XRpcStruct; + if (post == null) + return; + + var postId = post.Optional("postid"); + var contentItem = _contentManager.Get(postId, VersionOptions.Latest); + if (contentItem == null) + return; + + var publishedUtc = contentItem.As().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 drivers) { + var user = ValidateUser(userName, password); + if (user == null) + return; + + var publishedUtc = content.Optional("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()) + return; + + _authorizationService.CheckAccess(Permissions.PublishOthersContent, user, null); + + contentItem.As().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 _process; + + public XmlRpcDriver(Action process) { + _process = process; + } + + public void Process(object item) { + _process(item); + } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Services/XmlRpcHandler.cs b/src/Orchard.Web/Modules/Orchard.Tags/Services/XmlRpcHandler.cs index 6084761b9..8d2e31ac4 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Services/XmlRpcHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Services/XmlRpcHandler.cs @@ -41,7 +41,7 @@ namespace Orchard.Tags.Services { switch (context.Request.MethodName) { case "metaWeblog.getCategories": // hack... because live writer still asks for it... if (context.Response == null) - context.Response = new XRpcMethodResponse(); + context.Response = new XRpcMethodResponse().Add(new XRpcArray()); break; case "wp.getTags": var tags = MetaWeblogGetTags(