private bool UpdateWeblog(bool publish)
        {
            using (new WaitCursor())
            {
                // save all pending edits
                if (!SaveToDrafts())
                    return false;

                // upload to the weblog
                using (UpdateWeblogProgressForm updateWeblogProgressForm =
                    new UpdateWeblogProgressForm(_mainFrameWindow, this, BlogPost.IsPage, BlogName, publish))
                {
                    updateWeblogProgressForm.PrePublish += PrePublishHooks;
                    updateWeblogProgressForm.Publishing += BeforePublish;
                    updateWeblogProgressForm.PostPublish += PostPublishHooks;

                    // show the progress form
                    DialogResult result = updateWeblogProgressForm.ShowDialog(_mainFrameWindow);

                    // return success or failure
                    if (result == DialogResult.OK)
                    {
                        return true;
                    }
                    else if (result == DialogResult.Abort)
                    {
                        if (updateWeblogProgressForm.CancelReason != null)
                            DisplayMessage.Show(MessageId.PublishCanceledByPlugin, _mainFrameWindow, updateWeblogProgressForm.CancelReason);
                        return false;
                    }
                    else
                    {
                        if (updateWeblogProgressForm.Exception != null)
                            Trace.Fail(updateWeblogProgressForm.Exception.ToString());

                        // if this was a failure to upload images using the Metaweblog API newMediaObject
                        // then provide a special error message form that allows the user to reconfigure
                        // their file upload settings to another destination (e.g. FTP)
                        if (updateWeblogProgressForm.Exception is BlogClientFileUploadNotSupportedException)
                        {
                            result = FileUploadFailedForm.Show(_mainFrameWindow, GetUniqueImagesInPost());
                            if (result == DialogResult.Yes)
                                _editingSite.ConfigureWeblogFtpUpload(Blog.Id);
                        }
                        else if (updateWeblogProgressForm.Exception is BlogClientOperationCancelledException)
                        {
                            // show no UI for operation cancelled
                            Debug.WriteLine("BlogClient operation cancelled");
                        }
                        else
                        {
                            _blog.DisplayException(_mainFrameWindow, updateWeblogProgressForm.Exception);
                        }

                        // return failure
                        return false;
                    }
                }
            }
        }
        private void PostPublishHooks(object sender, UpdateWeblogProgressForm.PublishEventArgs args)
        {
            Debug.Assert(!_mainFrameWindow.InvokeRequired, "PostPublishHooks invoked on non-UI thread");

            UpdateWeblogProgressForm form = (UpdateWeblogProgressForm)sender;
            bool publish = args.Publish;

            foreach (ContentSourceInfo csi in ContentSourceManager.GetActivePublishNotificationPlugins(form, Blog.Id))
            {
                form.SetProgressMessage(string.Format(CultureInfo.InvariantCulture, Res.Get(StringId.PluginPublishProgress), csi.Name));
                IProperties properties =
                    ((IBlogPostEditingContext)this).ExtensionDataList.GetOrCreateExtensionData(csi.Id).Settings;

                try
                {
                    ((PublishNotificationHook)csi.Instance).OnPostPublish(form, properties, _publishingContext, publish);
                }
                catch (Exception ex)
                {
                    DisplayPluginException(form, csi, ex);
                    continue;
                }
            }
            form.SetProgressMessage(null);
        }
 public PublishOperationManager(UpdateWeblogProgressForm form, Blog blog)
 {
     _form = form;
     _blog = blog;
 }
        private void PrePublishHooks(object sender, UpdateWeblogProgressForm.PublishEventArgs args)
        {
            Debug.Assert(!_mainFrameWindow.InvokeRequired, "PrePublishHooks invoked on non-UI thread");

            UpdateWeblogProgressForm form = (UpdateWeblogProgressForm)sender;
            bool publish = args.Publish;

            // Let built in plugins do any extra processing they need to do during publish time
            PublishOperationManager publishOperationManager = new PublishOperationManager(form, Blog);
            string contents = SmartContentWorker.PerformOperation(_publishingContext.PostInfo.Contents, publishOperationManager.DoPublishWork, true, (IContentSourceSidebarContext)_publishingContext, false);

            // One of the built in plugins threw an exception and we must cancel publish
            if (publishOperationManager.Exception != null)
            {
                if (!(publishOperationManager.Exception is CancelPublishException))
                {
                    UnhandledExceptionErrorMessage message = new UnhandledExceptionErrorMessage();
                    message.ShowMessage(_mainFrameWindow, publishOperationManager.Exception);
                }
                args.Cancel = true;
                args.CancelReason = null;
                return;
            }

            // We only save the new html if there was no exception while creating it.
            BlogPost.Contents = contents;
            LocalFile.SaveBlogPost(this as IBlogPostEditingContext);

            foreach (ContentSourceInfo csi in ContentSourceManager.GetActivePublishNotificationPlugins(form, Blog.Id))
            {
                form.SetProgressMessage(string.Format(CultureInfo.InvariantCulture, Res.Get(StringId.PluginPublishProgress), csi.Name));
                IProperties properties =
                    ((IBlogPostEditingContext)this).ExtensionDataList.GetOrCreateExtensionData(csi.Id).Settings;

                try
                {
                    if (!((PublishNotificationHook)csi.Instance).OnPrePublish(form, properties, _publishingContext, publish))
                    {
                        args.Cancel = true;
                        args.CancelReason = csi.Name;
                        return;
                    }
                }
                catch (Exception e)
                {
                    DisplayPluginException(form, csi, e);
                    continue;
                }
            }
            form.SetProgressMessage(null);
        }
        private void BeforePublish(object sender, UpdateWeblogProgressForm.PublishingEventArgs args)
        {
            UpdateWeblogProgressForm form = (UpdateWeblogProgressForm)sender;

            bool noPluginsEnabled;
            if (!HeaderAndFooterPrerequisitesMet(form, out noPluginsEnabled))
            {
                Debug.Assert(!noPluginsEnabled, "No plugins enabled yet header/footer prerequisites met!?");
                args.RepublishOnSuccess = true;
                return;
            }

            if (noPluginsEnabled)
                return;

            BlogPost.Contents = SmartContentInsertionHelper.StripDivsWithClass(BlogPost.Contents, ContentSourceManager.HEADERS_FOOTERS);

            foreach (ContentSourceInfo csi in ContentSourceManager.GetActiveHeaderFooterPlugins(form, Blog.Id))
            {
                form.SetProgressMessage(string.Format(CultureInfo.InvariantCulture, Res.Get(StringId.PluginPublishProgress), csi.Name));

                HeaderFooterSource plugin = (HeaderFooterSource)csi.Instance;
                if (plugin.RequiresPermalink && string.IsNullOrEmpty(BlogPost.Permalink))
                {
                    Trace.WriteLine("Skipping plugin " + csi.Name + " because the post has no permalink");
                    continue;
                }
                IExtensionData extData =
                    ((IBlogPostEditingContext)this).ExtensionDataList.GetOrCreateExtensionData(csi.Id);
                SmartContent smartContent = new SmartContent(extData);
                HeaderFooterSource.Position position;
                string html;
                try
                {
                    html = plugin.GeneratePublishHtml(form, smartContent, _publishingContext, args.Publish, out position);
                }
                catch (Exception e)
                {
                    DisplayPluginException(form, csi, e);
                    continue;
                }

                if (string.IsNullOrEmpty(html))
                    continue;

                if (SmartContentInsertionHelper.ContainsUnbalancedDivs(html))
                {
                    Trace.Fail("Unbalanced divs detected in HTML generated by " + csi.Name + ": " + html);
                    DisplayMessage.Show(MessageId.MalformedHtmlIgnored, form, csi.Name);
                    continue;
                }

                // Don't use float alignment for footers--it causes them to float around
                // stuff that isn't part of the post
                bool noFloat = position == HeaderFooterSource.Position.Footer;
                string generatedHtml = SmartContentInsertionHelper.GenerateBlock(ContentSourceManager.HEADERS_FOOTERS, null, smartContent, false, html, noFloat, null);

                if (position == HeaderFooterSource.Position.Header)
                    BlogPost.Contents = generatedHtml + BlogPost.Contents;
                else if (position == HeaderFooterSource.Position.Footer)
                    BlogPost.Contents = BlogPost.Contents + generatedHtml;
                else
                    Debug.Fail("Unknown HeaderFooter position: " + position);
            }
            form.SetProgressMessage(null);

            BlogPost.Contents = HtmlLinebreakStripper.RemoveLinebreaks(BlogPost.Contents);
        }