public TickableProgressTick(IProgressHost progress,
     int ticks)
 {
     _progress = progress;
     _ticks = ticks;
     _currentTicks = 0;
 }
Example #2
0
 public override void CleanupRegions(IProgressHost progress)
 {
     if (temporaryPost != null)
     {
         // Delete the temporary post.
         DeletePost(temporaryPost, progress);
     }
 }
Example #3
0
        protected void UpdateProgress(IProgressHost progressHost, int percent, string message)
        {
            if (CancelRequested)
            {
                throw new OperationCancelledException();
            }

            progressHost.UpdateProgress(percent, 100, message);
        }
 public ProgressWorker(ProgressOperation method, ProgressCategory category, ProgressOperationCompleted completedMethod, int progressSize, int progressTotal, IProgressHost progress)
 {
     WorkerMethod = method;
     _category = category;
     CompletedMethod = completedMethod;
     ProgressSize = progressSize;
     ParentProgress = progress;
     TotalProgressTicks = progressTotal;
 }
Example #5
0
 public ProgressWorker(ProgressOperation method, ProgressCategory category, ProgressOperationCompleted completedMethod, int progressSize, int progressTotal, IProgressHost progress)
 {
     WorkerMethod       = method;
     _category          = category;
     CompletedMethod    = completedMethod;
     ProgressSize       = progressSize;
     ParentProgress     = progress;
     TotalProgressTicks = progressTotal;
 }
Example #6
0
        public override void CleanupRegions(IProgressHost progress)
        {
            if (blogHomepageContents != null)
            {
                blogHomepageContents.Close();
                blogHomepageContents = null;
            }

            progress.UpdateProgress(100, 100);
        }
        public JointProgressHosts(IProgressHost parentProgressHost, int slices, int tickAllocation, int tickTotal)
        {
            this.pHost = parentProgressHost;
            this.tickAllocation = tickAllocation;
            this.tickTotal = tickTotal;
            this.startPercentage = parentProgressHost.ProgressCompletionPercentage;

            this.ticks = new LinkedProgressTick[slices];
            for (int i = 0; i < ticks.Length; i++)
                ticks[i] = new LinkedProgressTick(this);
        }
Example #8
0
        private double lastCompletionPercentage; //the %complete of this tick.

        /// <summary>
        ///
        /// </summary>
        /// <param name="progress">the parent progress host that this tick is nested within</param>
        /// <param name="tickAllocation">the number of ticks allocated for use by this object</param>
        /// <param name="tickTotal">the total number of ticks in the overall parent progress operation</param>
        public ProgressTick(IProgressHost progress, int tickAllocation, int tickTotal)
        {
            ParentProgress = progress;

            //remember the initial completion percentage of the parent so that this object
            //will always add that percentage when updating progress.
            StartPercentage = ParentProgress.ProgressCompletionPercentage;

            TickAllocation = tickAllocation;
            TickTotal      = tickTotal;
        }
        private double lastCompletionPercentage; //the %complete of this tick.

        /// <summary>
        ///
        /// </summary>
        /// <param name="progress">the parent progress host that this tick is nested within</param>
        /// <param name="tickAllocation">the number of ticks allocated for use by this object</param>
        /// <param name="tickTotal">the total number of ticks in the overall parent progress operation</param>
        public ProgressTick(IProgressHost progress, int tickAllocation, int tickTotal)
        {
            ParentProgress = progress;

            //remember the initial completion percentage of the parent so that this object
            //will always add that percentage when updating progress.
            StartPercentage = ParentProgress.ProgressCompletionPercentage;

            TickAllocation = tickAllocation;
            TickTotal = tickTotal;
        }
 public static string Thin(IHTMLElement startElement, bool preserveImages, IProgressHost progressHost)
 {
     StringBuilder escapedText = new StringBuilder();
     if (startElement != null)
     {
         IHTMLElementCollection elements = (IHTMLElementCollection)startElement.all;
         TickableProgressTick progress = new TickableProgressTick(progressHost, elements.length + 1);
         IHTMLDOMNode startNode = (IHTMLDOMNode) startElement;
         StripChildNodes(startNode, escapedText, preserveImages, progress);
     }
     return escapedText.ToString();
 }
        /// <summary>
        /// Creates a set of BlogTemplateFiles using a specific region locator strategy.
        /// </summary>
        /// <param name="progress"></param>
        /// <param name="regionLocatorStrategy"></param>
        /// <param name="templateStrategies"></param>
        /// <param name="templateTypes"></param>
        /// <returns></returns>
        private BlogEditingTemplateFile[] GetBlogTemplateFiles(IProgressHost progress, BlogPostRegionLocatorStrategy regionLocatorStrategy, BlogEditingTemplateStrategy[] templateStrategies, BlogEditingTemplateType[] templateTypes)
        {
            BlogEditingTemplateFile[] blogTemplateFiles = null;
            try
            {
                regionLocatorStrategy.PrepareRegions(new ProgressTick(progress, 25, 100));

                ArrayList    templateFiles = new ArrayList();
                ProgressTick tick          = new ProgressTick(progress, 50, 100);
                for (int i = 0; i < templateTypes.Length; i++)
                {
                    ProgressTick parseTick = new ProgressTick(tick, 1, templateTypes.Length);
                    try
                    {
                        CheckCancelRequested(parseTick);
                        templateStrategy = templateStrategies[i];

                        // Parse the blog post HTML into an editing template.
                        // Note: we can't use MarkupServices to parse the document from a non-UI thread,
                        // so we have to execute the parsing portion of the template download operation on the UI thread.
                        string editingTemplate = ParseWebpageIntoEditingTemplate_OnUIThread(_parentControl, regionLocatorStrategy, new ProgressTick(parseTick, 1, 5));

                        // check for cancel
                        CheckCancelRequested(parseTick);

                        string baseUrl = HTMLDocumentHelper.GetBaseUrl(editingTemplate, _blogHomepageUrl);

                        // Download the template stylesheets and embedded resources (this lets the editing template load faster..and works offline!)
                        string templateFile = DownloadTemplateFiles(editingTemplate, baseUrl, new ProgressTick(parseTick, 4, 5));
                        templateFiles.Add(new BlogEditingTemplateFile(templateTypes[i], templateFile));
                    }
                    catch (BlogClientAbortGettingTemplateException)
                    {
                        Trace.WriteLine(String.Format(CultureInfo.CurrentCulture, "Failed to download template {0}.  Aborting getting further templates", templateTypes[i].ToString()));
                        throw;
                    }
                    catch (Exception e)
                    {
                        Trace.WriteLine(String.Format(CultureInfo.CurrentCulture, "Failed to download template {0}: {1}", templateTypes[i].ToString(), e.ToString()));
                    }
                }
                if (templateFiles.Count > 0)
                {
                    blogTemplateFiles = (BlogEditingTemplateFile[])templateFiles.ToArray(typeof(BlogEditingTemplateFile));
                }
            }
            finally
            {
                regionLocatorStrategy.CleanupRegions(new ProgressTick(progress, 25, 100));
            }
            return(blogTemplateFiles);
        }
Example #12
0
 private async Task <RsdServiceDescription> GetRsdServiceDescription(IProgressHost progressHost, HomepageDom weblogDOM)
 {
     if (weblogDOM != null)
     {
         // try to download an RSD description
         UpdateProgress(progressHost, 50, "Analysing interface");
         return(await RsdServiceDetector.DetectFromWeblogAsync(_homepageUrl, weblogDOM));
     }
     else
     {
         return(null);
     }
 }
Example #13
0
        public static string Thin(IHTMLElement startElement, bool preserveImages, IProgressHost progressHost)
        {
            StringBuilder escapedText = new StringBuilder();

            if (startElement != null)
            {
                IHTMLElementCollection elements  = (IHTMLElementCollection)startElement.all;
                TickableProgressTick   progress  = new TickableProgressTick(progressHost, elements.length + 1);
                IHTMLDOMNode           startNode = (IHTMLDOMNode)startElement;
                StripChildNodes(startNode, escapedText, preserveImages, progress);
            }
            return(escapedText.ToString());
        }
Example #14
0
 private RsdServiceDescription GetRsdServiceDescription(IProgressHost progressHost, IHTMLDocument2 weblogDOM)
 {
     if (weblogDOM != null)
     {
         // try to download an RSD description
         UpdateProgress(progressHost, 50, Res.Get(StringId.ProgressAnalyzingInterface));
         return(RsdServiceDetector.DetectFromWeblog(_homepageUrl, weblogDOM));
     }
     else
     {
         return(null);
     }
 }
        public JointProgressHosts(IProgressHost parentProgressHost, int slices, int tickAllocation, int tickTotal)
        {
            this.pHost           = parentProgressHost;
            this.tickAllocation  = tickAllocation;
            this.tickTotal       = tickTotal;
            this.startPercentage = parentProgressHost.ProgressCompletionPercentage;

            this.ticks = new LinkedProgressTick[slices];
            for (int i = 0; i < ticks.Length; i++)
            {
                ticks[i] = new LinkedProgressTick(this);
            }
        }
Example #16
0
        public override BlogPostRegions LocateRegionsOnUIThread(IProgressHost progress)
        {
            blogHomepageContents.Seek(0, SeekOrigin.Begin);
            IHTMLDocument2 doc2 = HTMLDocumentHelper.GetHTMLDocumentFromStream(blogHomepageContents, _blogHomepageUrl);

            // Ensure that the document is fully loaded.
            // If it is not fully loaded, then viewing its current style is non-deterministic.
            DateTime startedDoingEvents = DateTime.Now;

            while (!progress.CancelRequested && !HTMLDocumentHelper.IsReady(doc2))
            {
                if (DateTime.Now.Subtract(startedDoingEvents).TotalMilliseconds > 10000)
                {
                    // Timing out here is not fatal.
                    Trace.WriteLine("Timed out while loading blog homepage for theme detection.");
                    break;
                }

                Application.DoEvents();
            }

            //The Google/Blogger dynamic templates load the pages dynmaically usig Ajax, so we dont have any template to use.
            if (IsUsingDynamicTemplate(doc2))
            {
                throw new BlogClientAbortGettingTemplateException();
            }

            IHTMLElement[] titles = FindText(_titleText, doc2.body);
            IHTMLElement[] bodies = FindText(_bodyText, doc2.body);
            if (titles.Length == 0 || bodies.Length == 0)
            {
                throw new Exception("Unable to locate blog post elements using most recent post");
            }

            if (IsSmartContent(bodies[0]))
            {
                throw new Exception("Most recent post is smart content");
            }

            BlogPostRegions regions = new BlogPostRegions();

            regions.TitleRegions = titles;

            //scrub the post body element to avoid improperly including extraneous parent elements
            regions.BodyRegion = ScrubPostBodyRegionParentElements(bodies[0]);
            regions.Document   = doc2;

            progress.UpdateProgress(100, 100);

            return(regions);
        }
Example #17
0
        public override void PrepareRegions(IProgressHost progress)
        {
            TempPostWarningHelper helper = new TempPostWarningHelper(BlogClientUIContext.ContextForCurrentThread);

            BlogClientUIContext.ContextForCurrentThread.Invoke(new ThreadStart(helper.ShowWarningDialog), null);

            if (helper.DialogResult == DialogResult.Yes)
            {
                PrepareRegionsUsingTemporaryPost(progress);
            }
            else
            {
                throw new OperationCancelledException();
            }
        }
Example #18
0
 private void DeletePost(BlogPost post, IProgressHost progress)
 {
     try
     {
         progress.UpdateProgress(Res.Get(StringId.ProgressFinalizingEditingTemplateConfig));
         _blogClient.DeletePost(_blogAccount.BlogId, post.Id, true);
         progress.UpdateProgress(100, 100);
     }
     catch (Exception ex)
     {
         Trace.Fail("Unexpected exception occurred while deleting temporary post: " + ex.ToString());
         //show a message that user needs to delete their post
         DisplayMessage.Show(MessageId.TempPostDeleteFailed);
     }
 }
Example #19
0
        /// <summary>
        /// Downloads a webpage from a blog and searches for TEMPORARY_POST_TITLE_GUID.
        /// </summary>
        /// <param name="blogPageUrl"></param>
        /// <param name="progress"></param>
        /// <returns>Stream containing document which contains TEMPORARY_POST_TITLE_GUID.</returns>
        private Stream DownloadBlogPage(string blogPageUrl, IProgressHost progress)
        {
            ProgressTick   tick      = new ProgressTick(progress, 50, 100);
            MemoryStream   memStream = new MemoryStream();
            IHTMLDocument2 doc2      = null;

            // WinLive 221984: Theme detection timing out intermittently on WordPress.com
            // The temp post *often* takes more than a minute to show up on the blog home page.
            // The download progress dialog has a cancel button, we'll try a lot before giving up.
            for (int i = 0; i < 30 && doc2 == null; i++)
            {
                if (progress.CancelRequested)
                {
                    throw new OperationCancelledException();
                }
                tick.UpdateProgress(0, 0, Res.Get(StringId.ProgressDownloadingWeblogEditingStyle));
                // Sleep to give the post enough time to show up.
                // We'll make 10 attempts with a 1 second delay.
                // Subsequent attempts will use a 10 second delay.
                // This means we'll try for 5 minutes (10s + 290s = 300s) before we consider the operation timed out.
                Thread.Sleep(i < 10 ? 1000 : 10000);

                // Add random parameter to URL to bypass cache
                var urlRandom = UrlHelper.AppendQueryParameters(blogPageUrl, new string[] { Guid.NewGuid().ToString() });

                HttpWebResponse resp = _pageDownloader(urlRandom, 60000);
                memStream = new MemoryStream();
                using (Stream respStream = resp.GetResponseStream())
                    StreamHelper.Transfer(respStream, memStream);

                //read in the HTML file and determine if it contains the title element
                memStream.Seek(0, SeekOrigin.Begin);
                doc2 = HTMLDocumentHelper.GetHTMLDocumentFromStream(memStream, urlRandom);
                if (HTMLDocumentHelper.FindElementContainingText(doc2, TEMPORARY_POST_TITLE_GUID) == null)
                {
                    doc2 = null;
                }
            }
            if (doc2 == null)
            {
                throw new OperationTimedOutException();
            }
            tick.UpdateProgress(100, 100);

            //return the stream
            memStream.Seek(0, SeekOrigin.Begin);
            return(memStream);
        }
        /// <summary>
        /// Downloads the Document for a particular URL
        /// </summary>
        private void DoDownload(IProgressHost progressHost)
        {
            if (_downloader == null)
            {
                _downloader = new WebPageDownloader(_parentControl);
            }

            // Configure the downloader, hook its complete event and start the download
            _downloader.Title             = _title;
            _downloader.Url               = CleanUrl(_url);
            _downloader.ExecuteScripts    = _permitScriptExecution;
            _downloader.CookieString      = CookieString;
            _downloader.PostData          = _postData;
            _downloader.DownloadComplete += new EventHandler(downloader_DownloadComplete);
            _downloader.DownloadFromUrl(progressHost);
        }
Example #21
0
 public object DownloadFromUrl(IProgressHost progressHost)
 {
     this.progressHost = progressHost;
     try
     {
         HookEvents();
         DownloadIsComplete = false;
         browserControl.Navigate(Url, false, null, PostData);
     }
     catch
     {
         UnHookEvents(false);
         throw;
     }
     return(this);
 }
Example #22
0
        /// <summary>
        /// Fetch a blog page from the URL specified and transfer it into blogPageContents
        /// </summary>
        /// <param name="progress"></param>
        /// <param name="url"></param>
        public override void FetchTemporaryPostPage(IProgressHost progress, string url)
        {
            blogPageContents = new MemoryStream();

            // Download the webpage that is contains the temporary blog post
            // WARNING, DownloadBlogPage uses an MSHTML Document on a non-UI thread...which is a no-no!
            //   its been this way through several betas without problem, so we'll keep it that way for now, but
            //   it needs to be fixed eventually.
            Stream postHtmlContents = DownloadBlogPage(url, progress);

            CheckCancelRequested(progress);

            using (postHtmlContents)
            {
                StreamHelper.Transfer(postHtmlContents, blogPageContents);
            }
            progress.UpdateProgress(100, 100);
        }
Example #23
0
        public override void PrepareRegions(IProgressHost progress)
        {
            BlogPost[] posts = _blogClient.GetRecentPosts(_blogAccount.BlogId, 1, false, DateTime.UtcNow);
            if (posts == null || posts.Length == 0)
            {
                recentPostCount = 0;
                throw new Exception("No recent posts available");
            }
            else
            {
                recentPostCount = posts.Length;
            }

            mostRecentPost = posts[0];
            _titleText     = HTMLDocumentHelper.HTMLToPlainText(mostRecentPost.Title);
            _bodyText      = HTMLDocumentHelper.HTMLToPlainText(mostRecentPost.MainContents);

            string normalizedTitleText = NormalizeText(_titleText);
            string normalizedBodyText  = NormalizeText(_bodyText);

            //verify the normalized content is unique enough to distinctly identify the post regions
            if (normalizedTitleText.Length < 4)
            {
                throw new ArgumentException("Title text is not unique enough to use for style detection");
            }
            if (normalizedBodyText.Length < 8 || normalizedBodyText.IndexOf(' ') == -1)
            {
                throw new ArgumentException("Content text is not unique enough to use for style detection");
            }
            if (normalizedBodyText.IndexOf(normalizedTitleText, StringComparison.CurrentCulture) != -1) //title text is a subset of the body text
            {
                throw new ArgumentException("Title text is not unique enough to use for style detection");
            }
            if (normalizedTitleText.IndexOf(normalizedBodyText, StringComparison.CurrentCulture) != -1) //body text is a subset of the title text
            {
                throw new ArgumentException("Content text is not unique enough to use for style detection");
            }

            blogHomepageContents = DownloadBlogPage(_blogHomepageUrl, progress);
        }
Example #24
0
        private void PrepareRegionsUsingTemporaryPost(IProgressHost progress)
        {
            // Publish a temporary post so that we can examine HTML that will surround posts created with the editor
            temporaryPost = PostTemplate(new ProgressTick(progress, 25, 100));
            CheckCancelRequested(progress);

            blogHomepageContents = new MemoryStream();

            // Download the webpage that is contains the temporary blog post
            // WARNING, DownloadBlogPage uses an MSHTML Document on a non-UI thread...which is a no-no!
            //   its been this way through several betas without problem, so we'll keep it that way for now, but
            //   it needs to be fixed eventually.
            Stream postHtmlContents = DownloadBlogPage(_blogHomepageUrl, progress);

            CheckCancelRequested(progress);

            using (postHtmlContents)
            {
                StreamHelper.Transfer(postHtmlContents, blogHomepageContents);
            }
            progress.UpdateProgress(100, 100);
        }
Example #25
0
        private PageToDownload DownloadUrl(string url, PageToDownload parent, IProgressHost progress)
        {
            PageToDownload thisPageToDownload = null;

            // Download the current page
            LightWeightHTMLDocument lightWeightDoc = null;

            using (HTMLDocumentDownloader downloader = new HTMLDocumentDownloader(_parentControl, url, null, _context.CookieString, _context.TimeoutMS, true))
            {
                downloader.DownloadHTMLDocument(progress);
                lightWeightDoc     = LightWeightHTMLDocument.FromIHTMLDocument2(downloader.HtmlDocument, downloader.Url);
                thisPageToDownload = new PageToDownload(lightWeightDoc, url, null, parent);
                // Reset the url in the event that a redirect occurred
                thisPageToDownload.AbsoluteUrl = downloader.Url;
            }

            foreach (HTMLDocumentHelper.ResourceUrlInfo styleUrl in lightWeightDoc.StyleResourcesUrls)
            {
                thisPageToDownload.AddReference(new ReferenceToDownload(styleUrl.ResourceUrl, thisPageToDownload, styleUrl.ResourceAbsoluteUrl));
            }

            return(thisPageToDownload);
        }
        private string DownloadManifestTemplate(IProgressHost progress, string manifestTemplateUrl)
        {
            try
            {
                // update progress
                progress.UpdateProgress(0, 100, Res.Get(StringId.ProgressDownloadingEditingTemplate));

                // process any parameters within the url
                string templateUrl = BlogClientHelper.FormatUrl(manifestTemplateUrl, _blogHomepageUrl, _blogAccount.PostApiUrl, _blogAccount.BlogId);

                // download the url
                using (StreamReader streamReader = new StreamReader(_blogClient.SendAuthenticatedHttpRequest(templateUrl, 20000, null).GetResponseStream()))
                    return(streamReader.ReadToEnd());
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Exception occurred while attempting to download template from " + manifestTemplateUrl + " :" + ex.ToString());
                return(null);
            }
            finally
            {
                progress.UpdateProgress(100, 100);
            }
        }
Example #27
0
 public MultiThreadedPageDownloader(int threadCount, IProgressHost progressHost)
 {
     _threadCount  = threadCount;
     _progressHost = progressHost;
 }
 public CancelOnlyProgressHost(IProgressHost parent)
 {
     this.parent = parent;
 }
        /// <summary>
        /// Actually downloads the pages
        /// </summary>
        private PageToDownload[] DownloadPages(IProgressHost progress, string url, LightWeightHTMLDocument lightWeightDocument, PageToDownload parentPageToDownload)
        {
            // Check for cancel
            if (progress.CancelRequested)
                throw new OperationCancelledException();

            _currentDepth++;
            ArrayList downloadedPages = new ArrayList();

            // Set up our progress
            int thisPageTicks = FIRSTPAGETICKS;
            if (_context.Depth == _currentDepth)
                thisPageTicks = TOTALTICKS;
            ProgressTick firstPagedownloadProgress = new ProgressTick(progress, thisPageTicks, TOTALTICKS);

            string safeUrl = UrlHelper.GetUrlWithoutAnchorIdentifier(url);

            // Look up the content type of this pageToDownload
            UrlContentTypeInfo headerInfo = null;
            if (_headerInfo.ContainsKey(safeUrl))
            {
                headerInfo = (UrlContentTypeInfo)_headerInfo[safeUrl];
            }
            else
            {
                if (lightWeightDocument != null)
                    headerInfo = new UrlContentTypeInfo("text/html", url);
                else if (headerInfo == null && !_context.IsTimedOutUrl(url) && _context.ShouldDownloadThisUrl(url))
                {
                    progress.UpdateProgress(string.Format(CultureInfo.CurrentCulture, Res.Get(StringId.ProgressDeterminingType), url));
                    if (lightWeightDocument == null)
                        headerInfo = ContentTypeHelper.ExpensivelyGetUrlContentType(url, _context.TimeoutMS);
                    else
                        headerInfo = ContentTypeHelper.InexpensivelyGetUrlContentType(url);
                }
                _headerInfo.Add(safeUrl, headerInfo);
            }

            // If this is a web page and we should download it, do it!
            if ((lightWeightDocument != null && IsDownloadablePageResource(headerInfo)) ||
                (lightWeightDocument == null && IsDownloadablePageResource(headerInfo) && _context.ShouldDownloadThisUrl(headerInfo))
                )
            {
                bool downloadWorked = false;
                int downloadAttempts = -1;
                bool timedOut = true;

                // Max sure we are retrying the correct number of times
                ProgressTick pageDownloadProgress = new ProgressTick(firstPagedownloadProgress, 80, 100);
                while (!downloadWorked && downloadAttempts++ < _context.RetryCount && timedOut)
                {
                    timedOut = false;

                    pageDownloadProgress.UpdateProgress(0, 1);
                    try
                    {
                        // If we haven't downloaded this page yet download it
                        PageToDownload thisPageToDownload = null;

                        if (!_context.UrlAlreadyDownloaded(safeUrl))
                        {
                            if (lightWeightDocument == null)
                                thisPageToDownload = DownloadUrl(url, parentPageToDownload, pageDownloadProgress);
                            else
                            {
                                LightWeightHTMLDocument htmlDoc = lightWeightDocument;

                                // Only redownload if we absolutely need to
                                if (htmlDoc.HasFramesOrStyles && (htmlDoc.Frames == null || htmlDoc.StyleResourcesUrls == null))
                                {

                                    string html = htmlDoc.GenerateHtml();
                                    string tempFile = TempFileManager.Instance.CreateTempFile("temp.htm");
                                    using (StreamWriter writer = new StreamWriter(tempFile, false, Encoding.UTF8))
                                        writer.Write(html);
                                    using (HTMLDocumentDownloader downloader = new HTMLDocumentDownloader(_parentControl, UrlHelper.GetLocalFileUrl(tempFile), htmlDoc.Title, _context.CookieString, _context.TimeoutMS, false))
                                    {
                                        downloader.DownloadHTMLDocument(pageDownloadProgress);

                                        htmlDoc.UpdateBasedUponHTMLDocumentData(downloader.HtmlDocument, url);
                                    }
                                }
                                thisPageToDownload = new PageToDownload(htmlDoc, url, null, parentPageToDownload);
                                if (htmlDoc.StyleResourcesUrls != null)
                                    foreach (HTMLDocumentHelper.ResourceUrlInfo styleUrl in htmlDoc.StyleResourcesUrls)
                                        thisPageToDownload.AddReference(new ReferenceToDownload(styleUrl.ResourceUrl, thisPageToDownload, styleUrl.ResourceAbsoluteUrl));
                            }
                            // Add this page to our lists
                            _context.AddPageToDownload(safeUrl, thisPageToDownload, true);
                            downloadedPages.Add(thisPageToDownload);

                        }
                        else
                            thisPageToDownload = (PageToDownload)_context.CreatedPageToDownloadTable[safeUrl];

                        // If we're downloading a site, add a second copy of the root page in the references subdir
                        // This was, if the root page gets renamed, links back to it will still work correctly
                        // This is a bit of a hack, but otherwise, we'll need to escape urls whenever we output
                        // the site and change the root file name
                        if (thisPageToDownload.IsRootPage && _context.Depth > 0)
                        {
                            PageToDownload copyOfThisPageToDownload = new PageToDownload(thisPageToDownload.LightWeightHTMLDocument.Clone(), thisPageToDownload.UrlToReplace, thisPageToDownload.FileName, thisPageToDownload);
                            downloadedPages.Add(copyOfThisPageToDownload);
                        }

                        // enumerate the frames of this page and add them to the list of pages
                        PageToDownload[] subFramesToDownload = GetFramePagesToDownload(thisPageToDownload);
                        downloadedPages.AddRange(subFramesToDownload);
                        foreach (PageToDownload pageToDownload in subFramesToDownload)
                            _context.AddPageToDownload(pageToDownload.AbsoluteUrl, pageToDownload, false);

                        // Now drill down based upon the depth configuration
                        if (_context.ShouldContinue(_currentDepth))
                        {
                            ProgressTick otherPagesdownloadProgress = new ProgressTick(progress, TOTALTICKS - thisPageTicks, TOTALTICKS);
                            downloadedPages.AddRange(GetSubPagesToDownload(otherPagesdownloadProgress, downloadedPages, thisPageToDownload));
                        }
                        downloadWorked = true;
                        firstPagedownloadProgress.UpdateProgress(1, 1);

                    }
                    catch (OperationTimedOutException)
                    {
                        timedOut = true;
                    }
                    catch (WebPageDownloaderException htex)
                    {
                        HandleException(new Exception(htex.Message, htex));
                    }
                    catch (Exception ex)
                    {
                        HandleException(new Exception(String.Format(CultureInfo.CurrentCulture, "{0} could not be downloaded", _url), ex));
                    }
                }

                // If we never got the download to succeed, add it to the list of timed out Urls
                if (!downloadWorked && timedOut)
                {
                    _context.AddTimedOutUrl(_url);
                    firstPagedownloadProgress.UpdateProgress(1, 1);

                }
            }
            // If it isn't a page we'll just add the file to the reference list for the parent page
            // There is not an else, because we could be looking at a reference, but a reference that
            // should not be downloaded (in which case we just ignore it)
            else if (headerInfo != null && _context.ShouldDownloadThisUrl(headerInfo))
            {
                parentPageToDownload.AddReference(new ReferenceToDownload(url, parentPageToDownload));
                progress.UpdateProgress(1, 1);
            }

            progress.UpdateProgress(1, 1);

            _currentDepth--;
            return (PageToDownload[])downloadedPages.ToArray(typeof(PageToDownload));
        }
Example #30
0
 public ProgressWorker(ProgressOperation method, ProgressCategory category, int progressSize, int progressTotal, IProgressHost progress)
     : this(method, category, null, progressSize, progressTotal, progress)
 {
 }
        private string DownloadTemplateFiles(string templateContents, string templateUrl, IProgressHost progress)
        {
            progress.UpdateProgress(Res.Get(StringId.ProgressDownloadingSupportingFiles));
            FileBasedSiteStorage files = new FileBasedSiteStorage(_blogTemplateDir);

            // convert the string to a stream
            MemoryStream templateStream = new MemoryStream();
            StreamWriter writer         = new StreamWriter(templateStream, Encoding.UTF8);

            writer.Write(templateContents);
            writer.Flush();
            templateStream.Seek(0, SeekOrigin.Begin);

            //read the stream into a lightweight HTML.  Note that we use from LightWeightHTMLDocument.FromIHTMLDocument2
            //instead of LightWeightHTMLDocument.FromStream because from stream improperly shoves a saveFrom declaration
            //above the docType (bug 289357)
            IHTMLDocument2          doc  = HTMLDocumentHelper.StreamToHTMLDoc(templateStream, templateUrl, true);
            LightWeightHTMLDocument ldoc = LightWeightHTMLDocument.FromIHTMLDocument2(doc, templateUrl, true, false);

            PageDownloadContext downloadContext = new PageDownloadContext(0);

            ApplyCredentials(downloadContext, templateUrl);
            using (PageToDownloadFactory downloadFactory = new PageToDownloadFactory(ldoc, downloadContext, _parentControl))
            {
                //calculate the dependent styles and resources
                ProgressTick tick = new ProgressTick(progress, 50, 100);
                downloadFactory.CreatePagesToDownload(tick);
                tick.UpdateProgress(100, 100);

                //download the dependent styles and resources
                tick = new ProgressTick(progress, 50, 100);
                PageAndReferenceDownloader downloader = new PageAndReferenceDownloader(downloadFactory.PagesToDownload, files);
                this.ApplyCredentials(downloader, templateUrl);
                downloader.Download(tick);
                tick.UpdateProgress(100, 100);

                //Expand out the relative paths in the downloaded HTML file with absolute paths.
                //Note: this is necessary so that template resources are not improperly resolved relative
                //      to the location of the file the editor is editing.
                string blogTemplateFile = Path.Combine(_blogTemplateDir, files.RootFile);
                string origFile         = blogTemplateFile + ".token";
                File.Move(blogTemplateFile, origFile);
                string absPath = String.Format(CultureInfo.InvariantCulture, "file:///{0}/{1}", _blogTemplateDir.Replace('\\', '/'), downloader.PathToken);
                TextHelper.ReplaceInFile(origFile, downloader.PathToken, blogTemplateFile, absPath);
                File.Delete(origFile);

                //fix up the files
                FixupDownloadedFiles(blogTemplateFile, files, downloader.PathToken);

                //complete the progress.
                progress.UpdateProgress(100, 100);

                File.WriteAllText(blogTemplateFile + ".path", absPath);
                return(blogTemplateFile);
            }
        }
 public static string Thin(IHTMLElement startElement, IProgressHost progressHost)
 {
     return Thin(startElement, false, progressHost);
 }
        private bool AttemptRsdBasedDetection(IProgressHost progressHost, RsdServiceDescription rsdServiceDescription)
        {
            // always return alse for null description
            if (rsdServiceDescription == null)
                return false;

            string providerId = String.Empty;
            BlogAccount blogAccount = null;

            // check for a match on rsd engine link
            foreach (IBlogProvider provider in BlogProviderManager.Providers)
            {
                blogAccount = provider.DetectAccountFromRsdHomepageLink(rsdServiceDescription);
                if (blogAccount != null)
                {
                    providerId = provider.Id;
                    break;
                }
            }

            // if none found on engine link, match on engine name
            if (blogAccount == null)
            {
                foreach (IBlogProvider provider in BlogProviderManager.Providers)
                {
                    blogAccount = provider.DetectAccountFromRsdEngineName(rsdServiceDescription);
                    if (blogAccount != null)
                    {
                        providerId = provider.Id;
                        break;
                    }
                }
            }

            // No provider associated with the RSD file, try to gin one up (will only
            // work if the RSD file contains an API for one of our supported client types)
            if (blogAccount == null)
            {
                // try to create one from RSD
                blogAccount = BlogAccountFromRsdServiceDescription.Create(rsdServiceDescription);
            }

            // if we have an rsd-detected weblog
            if (blogAccount != null)
            {
                // confirm that the credentials are OK
                UpdateProgress(progressHost, 65, Res.Get(StringId.ProgressVerifyingInterface));
                BlogAccountDetector blogAccountDetector = new BlogAccountDetector(
                    blogAccount.ClientType, blogAccount.PostApiUrl, _credentials);

                if (blogAccountDetector.ValidateService())
                {
                    // copy basic account info
                    _providerId = providerId;
                    _serviceName = blogAccount.ServiceName;
                    _clientType = blogAccount.ClientType;
                    _hostBlogId = blogAccount.BlogId;
                    _postApiUrl = blogAccount.PostApiUrl;

                    // see if we can improve on the blog name guess we already
                    // have from the <title> element of the homepage
                    BlogInfo blogInfo = blogAccountDetector.DetectAccount(_homepageUrl, _hostBlogId);
                    if (blogInfo != null)
                        _blogName = blogInfo.Name;
                }
                else
                {
                    // report user-authorization error
                    ReportErrorAndFail(blogAccountDetector.ErrorMessageType, blogAccountDetector.ErrorMessageParams);
                }

                // success!
                return true;
            }
            else
            {
                // couldn't do it
                return false;
            }
        }
        /// <summary>
        /// Downloads the pages and their references, providing progress feedback
        /// </summary>
        /// <param name="progressHost">The progresshost to use for feedback</param>
        /// <returns>this</returns>
        public object Download(IProgressHost progressHost)
        {
            // Prepare the list of references to download
            progressHost.UpdateProgress(Res.Get(StringId.ProgressPreparingListOfFiles));
            foreach (PageToDownload pageToDownload in _pagesToDownload)
            {
                // Lay down a placeholder file with the correct file name
                try
                {
                    string destination = Path.Combine(_siteStorage.BasePath, pageToDownload.RelativePath);
                    destination = PathHelper.GetNonConflictingPath(destination);
                    pageToDownload.FileName = Path.GetFileName(destination);

                    using (Stream htmlStream = _siteStorage.Open(destination, AccessMode.Write)) { }
                }
                catch (Exception e)
                {
                    HandleException(e);
                }

                foreach (ReferenceToDownload reference in pageToDownload.References)
                {
                    // Don't add the same item more than once
                    if (!_referencesToDownload.ContainsKey(reference.AbsoluteUrl))
                        _referencesToDownload.Add(reference.AbsoluteUrl, reference);
                }
            }

            // Enqueue the work items
            progressHost.UpdateProgress(Res.Get(StringId.ProgressStartingDownloadOfReferences));
            IProgressHost[] progressHosts = new JointProgressHosts(progressHost, _referencesToDownload.Count, 8000, 10000).ProgressHosts;
            int tickNum = 0;
            foreach (ReferenceToDownload reference in _referencesToDownload.Values)
                workQueue.Enqueue(new DownloadWorkItem(reference, _siteStorage, progressHosts[tickNum++]));

            // Start up the parallel execution of the downloads
            ParallelExecution parallelExecution = new ParallelExecution(new ThreadStart(WorkerThreadStart), 2);
            parallelExecution.Execute();
            parallelExecution = null;

            // Now go through and get HTML for each page, and emit the HTML to disk
            ProgressTick allPagesProgress = new ProgressTick(progressHost, 2000, 10000);
            for (int i = 0; i < _pagesToDownload.Length; i++)
            {
                try
                {
                    allPagesProgress.UpdateProgress(i, _pagesToDownload.Length, string.Format(CultureInfo.CurrentCulture, Res.Get(StringId.ProgressSaving), _pagesToDownload[i].FileName));
                    WriteHtmlToDisk(_pagesToDownload[i], _siteStorage);
                }
                catch (Exception e)
                {
                    HandleException(e);
                }
                if (allPagesProgress.CancelRequested)
                    throw new OperationCancelledException();
            }

            // We're complete!
            progressHost.UpdateProgress(1, 1, Res.Get(StringId.ProgressDownloadFinished));

            return this;
        }
 /// <summary>
 /// Generates the list of pages to download, providing progress.  The operation
 /// can be very time consuming, particularly if the context specifies creating mulitiple
 /// levels of pagesToDownload
 /// </summary>
 /// <param name="progressHost">The progress host to use to provide feedback</param>
 /// <returns>this object</returns>
 public object CreatePagesToDownload(IProgressHost progressHost)
 {
     _pagesToDownload = DownloadPages(progressHost, _url, _lightWeightHTMLDocument, null);
     return null;
 }
        public object Download(IProgressHost progressHost)
        {
            ResetTimeoutState();

            _finalUrl = Url;
            ProgressHost = progressHost;
            // call the URLDownloadToFile (synchronous, notifies us of progress
            // via calls to IBindStatusCallback)
            SetCookies();
            int result = UrlMon.URLDownloadToFile(
                IntPtr.Zero, Url, FilePath, 0, this);

            // check for errors in the call
            // TODO: account for errors that we purposely generate (E_ACCESSDENIED)
            // HRESULT E_ABORT 0x80004004
            switch (result)
            {
                case HRESULT.S_OK:              // The download suceeded
                    break;
                case HRESULT.E_ABORT:           // The download has been cancelled
                                                //case HRESULT.E_ACCESSDENIED:	// no idea
                    if (progressHost.CancelRequested)
                        throw new OperationCancelledException();
                    break;
                default:
                    throw new COMException("Unable to download file " + Url, result);
            };
            return this;
        }
        protected void UpdateProgress(IProgressHost progressHost, int percent, string message)
        {
            if (CancelRequested)
                throw new OperationCancelledException();

            progressHost.UpdateProgress(percent, 100, message);
        }
        private object DetectWeblogSettings(IProgressHost progressHost)
        {
            using (BlogClientUIContextSilentMode uiContextScope = new BlogClientUIContextSilentMode()) //supress prompting for credentials
            {
                // no-op if we don't have a blog-id to work with
                if (HostBlogId == String.Empty)
                    return this;

                try
                {
                    // detect settings
                    BlogSettingsDetector blogSettingsDetector = new BlogSettingsDetector(this);
                    blogSettingsDetector.DetectSettings(progressHost);
                }
                catch (OperationCancelledException)
                {
                    // WasCancelled == true
                }
                catch (BlogClientOperationCancelledException)
                {
                    Cancel();
                    // WasCancelled == true
                }
                catch (Exception ex)
                {
                    Trace.Fail("Unexpected error occurred while detecting weblog settings: " + ex.ToString());
                }

                return this;
            }
        }
        protected IHTMLDocument2 GetWeblogHomepageDOM(IProgressHost progressHost)
        {
            // try download the weblog home page
            UpdateProgress(progressHost, 25, Res.Get(StringId.ProgressAnalyzingHomepage));
            string responseUri;
            IHTMLDocument2 weblogDOM = HTMLDocumentHelper.SafeGetHTMLDocumentFromUrl(_homepageUrl, out responseUri);
            if (responseUri != null && responseUri != _homepageUrl)
            {
                _homepageUrl = responseUri;
            }
            if (weblogDOM != null)
            {
                // default the blog name to the title of the document
                if (weblogDOM.title != null)
                {
                    _blogName = weblogDOM.title;

                    // drop anything to the right of a "|", as it usually is a site name
                    int index = _blogName.IndexOf("|", StringComparison.OrdinalIgnoreCase);
                    if (index > 0)
                    {
                        string newname = _blogName.Substring(0, index).Trim();
                        if (newname != String.Empty)
                            _blogName = newname;
                    }
                }
            }

            return weblogDOM;
        }
Example #40
0
 public ProgressContext(IProgressHost progressHost, int complete, string message)
 {
     _progressHost = progressHost;
     _progressHost.UpdateProgress(complete, 100, message);
 }
 protected abstract object DetectBlogService(IProgressHost progressHost);
        /// <summary>
        /// Download a reference, providing progress
        /// </summary>
        /// <param name="reference">The reference to download</param>
        /// <param name="fileStorage">The storage to download the refernce into</param>
        /// <param name="progressHost">The progressHost to provide feedback to</param>
        private void DownloadReference(ReferenceToDownload reference, FileBasedSiteStorage fileStorage, IProgressHost progressHost)
        {
            UrlDownloadToFile downloader;
            string fullPath;

            downloader = new UrlDownloadToFile();
            downloader.TimeoutMs = 30000;

            if (progressHost.CancelRequested)
                throw new OperationCancelledException();

            // make sure that the directory exists
            fullPath = Path.Combine(fileStorage.BasePath, reference.RelativePath);

            string directory = Path.GetDirectoryName(fullPath);
            if (!Directory.Exists(directory))
                Directory.CreateDirectory(directory);

            // Make sure there aren't any conflicts
            lock (this)
            {
                string newFileName = Path.GetFileName(fullPath);
                do
                {
                    fullPath = PathHelper.GetNonConflictingPath(fullPath);
                    newFileName = Path.GetFileName(fullPath);

                    reference.SetFileName(ref newFileName);

                } while (newFileName != Path.GetFileName(fullPath));

                using (File.Open(fullPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
                {
                }
            }

            string downloadUrl = reference.AbsoluteUrl;
            if (UrlHelper.IsFileUrl(downloadUrl))
                downloadUrl = HttpUtility.UrlDecode(downloadUrl);

            downloader.Url = downloadUrl.Trim();
            downloader.FilePath = fullPath;
            downloader.ShowSecurityUI = true;
            if (CredentialsContext != null)
                downloader.CredentialsContext = CredentialsContext;

            try
            {
                downloader.Download(progressHost);
            }
            catch (COMException e)
            {
                // If the file couldn't be downloaded, this doesn't matter.  But log it
                Trace.WriteLine("Didn't download file: " + downloader.Url + " " + e.ToString());
            }

            // Fix the filename of the downloaded entity to have the correct extension
            string contentType = downloader.ContentType;
            if (contentType != null && File.Exists(fullPath))
            {
                string suggestedExtension = MimeHelper.GetExtensionFromContentType(contentType);
                if (suggestedExtension == null)
                    suggestedExtension = UrlHelper.GetExtensionForUrl(downloader.FinalUrl);

                if (Path.GetExtension(fullPath) != suggestedExtension)
                {
                    string newFilePath = Path.ChangeExtension(fullPath, suggestedExtension);
                    string newFileName = Path.GetFileName(newFilePath);

                    // Try to reset the name until we can both agree
                    while (true)
                    {
                        newFilePath = PathHelper.GetNonConflictingPath(newFilePath);
                        newFileName = Path.GetFileName(newFilePath);

                        FileHelper.Rename(fullPath, newFilePath);
                        reference.SetFileName(ref newFileName);
                        if (newFileName != Path.GetFileName(newFilePath))
                        {
                            try
                            {
                                File.Delete(newFilePath);
                            }
                            catch (Exception e) { Debug.Fail("Unable to delete failed temp file: " + e.ToString()); }
                        }
                        else
                        {
                            break;
                        }
                    }

                    fullPath = newFilePath;
                }
            }

            // Handle anything special we need to do for stylesheet and js file references
            if (Path.GetExtension(fullPath) == ".css" && File.Exists(fullPath))
            {
                string fileContents = string.Empty;
                using (StreamReader reader = new StreamReader(fullPath))
                    fileContents = reader.ReadToEnd();

                if (fileContents != string.Empty)
                {
                    LightWeightCSSReplacer cssReplacer = new LightWeightCSSReplacer(fileContents);
                    // fix up references
                    foreach (ReferenceToDownload referenceInfo in _referencesToDownload.Values)
                        cssReplacer.AddUrlToReplace(new UrlToReplace(referenceInfo.UrlToReplace, referenceInfo.FileName));

                    string newCss = cssReplacer.DoReplace();
                    using (StreamWriter writer = new StreamWriter(fullPath, false))
                        writer.Write(newCss);
                }
            }
        }
        private PageToDownload DownloadUrl(string url, PageToDownload parent, IProgressHost progress)
        {
            PageToDownload thisPageToDownload = null;

            // Download the current page
            LightWeightHTMLDocument lightWeightDoc = null;

            using (HTMLDocumentDownloader downloader = new HTMLDocumentDownloader(_parentControl, url, null, _context.CookieString, _context.TimeoutMS, true))
            {
                downloader.DownloadHTMLDocument(progress);
                lightWeightDoc = LightWeightHTMLDocument.FromIHTMLDocument2(downloader.HtmlDocument, downloader.Url);
                thisPageToDownload = new PageToDownload(lightWeightDoc, url, null, parent);
                // Reset the url in the event that a redirect occurred
                thisPageToDownload.AbsoluteUrl = downloader.Url;
            }

            foreach (HTMLDocumentHelper.ResourceUrlInfo styleUrl in lightWeightDoc.StyleResourcesUrls)
                thisPageToDownload.AddReference(new ReferenceToDownload(styleUrl.ResourceUrl, thisPageToDownload, styleUrl.ResourceAbsoluteUrl));

            return thisPageToDownload;
        }
 public DownloadWorkItem(ReferenceToDownload reference, FileBasedSiteStorage siteStorage, IProgressHost progressHost)
 {
     this.reference = reference;
     this.siteStorage = siteStorage;
     this.progressHost = progressHost;
 }
        private PageToDownload[] GetSubPagesToDownload(IProgressHost progress, ArrayList downloadedPagesToScan, PageToDownload parentPage)
        {
            ArrayList subPages = new ArrayList();
            // enumerate the other downloads to do (if we're scanning)
            string[] subUrlsToDownload;
            if (_context.SelectedUrlsToDownload.Count < 1)
                subUrlsToDownload = GetSubPagesToDownload((PageToDownload[])downloadedPagesToScan.ToArray(typeof(PageToDownload)), parentPage);
            else
                subUrlsToDownload = (string[])_context.SelectedUrlsToDownload.ToArray(typeof(string));

            // do the other downloads, passing the context controlling depth
            foreach (string subUrl in subUrlsToDownload)
            {
                if (_context.ShouldContinue(_currentDepth))
                {
                    ProgressTick tick = new ProgressTick(progress, 1, subUrlsToDownload.Length);
                    subPages.AddRange(DownloadPages(tick, subUrl, null, parentPage));
                }
            }
            return (PageToDownload[])subPages.ToArray(typeof(PageToDownload));
        }
        /// <summary>
        /// Gets the body text for a given url
        /// </summary>
        /// <param name="url">The url to get the text for</param>
        /// <param name="timeout">The request timeout, in MS</param>
        /// <returns></returns>
        public static IHTMLDocument2 GetHTMLDocumentForUrl(string url, int timeout, IProgressHost progressHost)
        {
            WebRequestWithCache wr = new WebRequestWithCache(url);

            // return the html document
            return GetHTMLDocumentFromStream(wr.GetResponseStream(WebRequestWithCache.CacheSettings.CHECKCACHE, timeout), url);
        }
Example #47
0
 public ProgressWorker(ProgressOperation method, int progressSize, int progressTotal, IProgressHost progress)
     : this(method, null, null, progressSize, progressTotal, progress)
 {
 }
 public TickableProgressTick(IProgressHost progress, int totalTicks) : base(progress, 100, 100)
 {
     _totalTicks = totalTicks;
 }
Example #49
0
 public ProgressWorker(ProgressOperation method, ProgressOperationCompleted completedMethod, int progressSize, int progressTotal, IProgressHost progress)
     : this(method, null, completedMethod, progressSize, progressTotal, progress)
 {
 }
 public ProgressContext(IProgressHost progressHost, int complete, string message)
 {
     _progressHost = progressHost;
     _progressHost.UpdateProgress(complete, 100, message);
 }
 /// <summary>
 /// Creates a new filter.
 /// </summary>
 /// <param name="pHost">The underlying progress host.</param>
 /// <param name="filtered">The message types that should be EXCLUDED.</param>
 public ProgressHostFilter(IProgressHost pHost, MessageType filtered)
 {
     this.pHost = pHost;
     this.filtered = filtered;
 }
 private RsdServiceDescription GetRsdServiceDescription(IProgressHost progressHost, IHTMLDocument2 weblogDOM)
 {
     if (weblogDOM != null)
     {
         // try to download an RSD description
         UpdateProgress(progressHost, 50, Res.Get(StringId.ProgressAnalyzingInterface));
         return RsdServiceDetector.DetectFromWeblog(_homepageUrl, weblogDOM);
     }
     else
     {
         return null;
     }
 }
Example #53
0
 public MultiThreadedPageDownloader(IProgressHost progressHost) : this(2, progressHost)
 {
 }
 public CancelOnlyProgressHost(IProgressHost parent)
 {
     this.parent = parent;
 }
Example #55
0
        public object DetectSettings(IProgressHost progressHost)
        {
            using (_silentMode ? new BlogClientUIContextSilentMode() : null)
            {
                if (IncludeButtons || IncludeOptionOverrides || IncludeImages)
                {
                    using (new ProgressContext(progressHost, 40, Res.Get(StringId.ProgressDetectingWeblogSettings)))
                    {
                        // attempt to download editing manifest
                        WriterEditingManifest editingManifest = SafeDownloadEditingManifest();

                        if (editingManifest != null)
                        {
                            // always update the download info
                            if (editingManifest.DownloadInfo != null)
                            {
                                _context.ManifestDownloadInfo = editingManifest.DownloadInfo;
                            }

                            // images
                            if (IncludeImages)
                            {
                                // image if provided
                                if (editingManifest.Image != null)
                                {
                                    _context.Image = editingManifest.Image;
                                }

                                // watermark if provided
                                if (editingManifest.Watermark != null)
                                {
                                    _context.WatermarkImage = editingManifest.Watermark;
                                }
                            }

                            // buttons if provided
                            if (IncludeButtons && (editingManifest.ButtonDescriptions != null))
                            {
                                _context.ButtonDescriptions = editingManifest.ButtonDescriptions;
                            }

                            // option overrides if provided
                            if (IncludeOptionOverrides)
                            {
                                if (editingManifest.ClientType != null)
                                {
                                    _context.ClientType = editingManifest.ClientType;
                                }

                                if (editingManifest.OptionOverrides != null)
                                {
                                    _context.OptionOverrides = editingManifest.OptionOverrides;
                                }
                            }
                        }
                    }
                }

                using (new ProgressContext(progressHost, 40, Res.Get(StringId.ProgressDetectingWeblogCharSet)))
                {
                    if (IncludeOptionOverrides && IncludeHomePageSettings)
                    {
                        DetectHomePageSettings();
                    }
                }

                IBlogClient blogClient = CreateBlogClient();
                if (IncludeInsecureOperations || blogClient.IsSecure)
                {
                    if (blogClient is ISelfConfiguringClient)
                    {
                        // This must happen before categories detection but after manifest!!
                        ((ISelfConfiguringClient)blogClient).DetectSettings(_context, this);
                    }

                    // detect categories
                    if (IncludeCategories)
                    {
                        using (
                            new ProgressContext(progressHost, 20, Res.Get(StringId.ProgressDetectingWeblogCategories)))
                        {
                            BlogPostCategory[] categories = SafeDownloadCategories();
                            if (categories != null)
                            {
                                _context.Categories = categories;
                            }

                            BlogPostKeyword[] keywords = SafeDownloadKeywords();
                            if (keywords != null)
                            {
                                _context.Keywords = keywords;
                            }
                        }
                    }

                    // detect favicon (only if requested AND we don't have a PNG already
                    // for the small image size)
                    if (IncludeFavIcon)
                    {
                        using (new ProgressContext(progressHost, 10, Res.Get(StringId.ProgressDetectingWeblogIcon)))
                        {
                            byte[] favIcon = SafeDownloadFavIcon();
                            if (favIcon != null)
                            {
                                _context.FavIcon = favIcon;
                            }
                        }
                    }

                    if (IncludeImageEndpoints)
                    {
                        Debug.WriteLine("Detecting image endpoints");
                        ITemporaryBlogSettingsDetectionContext tempContext =
                            _context as ITemporaryBlogSettingsDetectionContext;
                        Debug.Assert(tempContext != null,
                                     "IncludeImageEndpoints=true but non-temporary context (type " +
                                     _context.GetType().Name + ") was used");
                        if (tempContext != null)
                        {
                            tempContext.AvailableImageEndpoints = null;
                            try
                            {
                                BlogInfo[] imageEndpoints = blogClient.GetImageEndpoints();
                                tempContext.AvailableImageEndpoints = imageEndpoints;
                                Debug.WriteLine(imageEndpoints.Length + " image endpoints detected");
                            }
                            catch (NotImplementedException)
                            {
                                Debug.WriteLine("Image endpoints not implemented");
                            }
                            catch (Exception e)
                            {
                                Trace.Fail("Exception detecting image endpoints: " + e.ToString());
                            }
                        }
                    }
                }
                // completed
                progressHost.UpdateProgress(100, 100, Res.Get(StringId.ProgressCompletedSettingsDetection));
            }

            return(this);
        }
        protected override object DetectBlogService(IProgressHost progressHost)
        {
            using (BlogClientUIContextSilentMode uiContextScope = new BlogClientUIContextSilentMode()) //supress prompting for credentials
            {
                try
                {
                    // get the weblog homepage and rsd service description if available
                    IHTMLDocument2 weblogDOM = GetWeblogHomepageDOM(progressHost);

                    // while we have the DOM available, scan for a writer manifest url
                    if (_manifestDownloadInfo == null)
                    {
                        string manifestUrl = WriterEditingManifest.DiscoverUrl(_homepageUrl, weblogDOM);
                        if (manifestUrl != String.Empty)
                            _manifestDownloadInfo = new WriterEditingManifestDownloadInfo(manifestUrl);
                    }

                    string html = weblogDOM != null ? HTMLDocumentHelper.HTMLDocToString(weblogDOM) : null;

                    bool detectionSucceeded = false;

                    if (!detectionSucceeded)
                        detectionSucceeded = AttemptGenericAtomLinkDetection(_homepageUrl, html, !ApplicationDiagnostics.PreferAtom);

                    if (!detectionSucceeded && _blogSettings.IsGoogleBloggerBlog)
                        detectionSucceeded = AttemptBloggerDetection(_homepageUrl, html);

                    if (!detectionSucceeded)
                    {
                        RsdServiceDescription rsdServiceDescription = GetRsdServiceDescription(progressHost, weblogDOM);

                        // if there was no rsd service description or we fail to auto-configure from the
                        // rsd description then move on to other auto-detection techniques
                        if (!(detectionSucceeded = AttemptRsdBasedDetection(progressHost, rsdServiceDescription)))
                        {
                            // try detection by analyzing the homepage url and contents
                            UpdateProgress(progressHost, 75, Res.Get(StringId.ProgressAnalyzingHomepage));
                            if (weblogDOM != null)
                                detectionSucceeded = AttemptHomepageBasedDetection(_homepageUrl, html);
                            else
                                detectionSucceeded = AttemptUrlBasedDetection(_homepageUrl);

                            // if we successfully detected then see if we can narrow down
                            // to a specific weblog
                            if (detectionSucceeded)
                            {
                                if (!BlogProviderParameters.UrlContainsParameters(_postApiUrl))
                                {
                                    // we detected the provider, now see if we can detect the weblog id
                                    // (or at lease the list of the user's weblogs)
                                    UpdateProgress(progressHost, 80, Res.Get(StringId.ProgressAnalyzingWeblogList));
                                    AttemptUserBlogDetection();
                                }
                            }
                        }
                    }

                    if (!detectionSucceeded && html != null)
                        AttemptGenericAtomLinkDetection(_homepageUrl, html, false);

                    // finished
                    UpdateProgress(progressHost, 100, String.Empty);
                }
                catch (OperationCancelledException)
                {
                    // WasCancelled == true
                }
                catch (BlogClientOperationCancelledException)
                {
                    Cancel();
                    // WasCancelled == true
                }
                catch (BlogAccountDetectorException ex)
                {
                    if (ApplicationDiagnostics.AutomationMode)
                        Trace.WriteLine(ex.ToString());
                    else
                        Trace.Fail(ex.ToString());
                    // ErrorOccurred == true
                }
                catch (Exception ex)
                {
                    // ErrorOccurred == true
                    Trace.Fail(ex.Message, ex.ToString());
                    ReportError(MessageId.WeblogDetectionUnexpectedError, ex.Message);
                }

                return this;
            }
        }
        public object DetectSettings(IProgressHost progressHost)
        {
            using (_silentMode ? new BlogClientUIContextSilentMode() : null)
            {
                if (IncludeButtons || IncludeOptionOverrides || IncludeImages)
                {
                    using (new ProgressContext(progressHost, 40, Res.Get(StringId.ProgressDetectingWeblogSettings)))
                    {
                        // attempt to download editing manifest
                        WriterEditingManifest editingManifest = SafeDownloadEditingManifest();

                        if (editingManifest != null)
                        {
                            // always update the download info
                            if (editingManifest.DownloadInfo != null)
                                _context.ManifestDownloadInfo = editingManifest.DownloadInfo;

                            // images
                            if (IncludeImages)
                            {
                                // image if provided
                                if (editingManifest.Image != null)
                                    _context.Image = editingManifest.Image;

                                // watermark if provided
                                if (editingManifest.Watermark != null)
                                    _context.WatermarkImage = editingManifest.Watermark;
                            }

                            // buttons if provided
                            if (IncludeButtons && (editingManifest.ButtonDescriptions != null))
                                _context.ButtonDescriptions = editingManifest.ButtonDescriptions;

                            // option overrides if provided
                            if (IncludeOptionOverrides)
                            {
                                if (editingManifest.ClientType != null)
                                    _context.ClientType = editingManifest.ClientType;

                                if (editingManifest.OptionOverrides != null)
                                    _context.OptionOverrides = editingManifest.OptionOverrides;
                            }
                        }
                    }
                }

                using (new ProgressContext(progressHost, 40, Res.Get(StringId.ProgressDetectingWeblogCharSet)))
                {
                    if (IncludeOptionOverrides && IncludeHomePageSettings)
                    {
                        DetectHomePageSettings();
                    }
                }

                IBlogClient blogClient = CreateBlogClient();
                if (IncludeInsecureOperations || blogClient.IsSecure)
                {
                    if (blogClient is ISelfConfiguringClient)
                    {
                        // This must happen before categories detection but after manifest!!
                        ((ISelfConfiguringClient)blogClient).DetectSettings(_context, this);
                    }

                    // detect categories
                    if (IncludeCategories)
                    {
                        using (
                            new ProgressContext(progressHost, 20, Res.Get(StringId.ProgressDetectingWeblogCategories)))
                        {
                            BlogPostCategory[] categories = SafeDownloadCategories();
                            if (categories != null)
                                _context.Categories = categories;

                            BlogPostKeyword[] keywords = SafeDownloadKeywords();
                            if (keywords != null)
                                _context.Keywords = keywords;
                        }
                    }

                    // detect favicon (only if requested AND we don't have a PNG already
                    // for the small image size)
                    if (IncludeFavIcon)
                    {
                        using (new ProgressContext(progressHost, 10, Res.Get(StringId.ProgressDetectingWeblogIcon)))
                        {
                            byte[] favIcon = SafeDownloadFavIcon();
                            if (favIcon != null)
                                _context.FavIcon = favIcon;
                        }
                    }

                    if (IncludeImageEndpoints)
                    {
                        Debug.WriteLine("Detecting image endpoints");
                        ITemporaryBlogSettingsDetectionContext tempContext =
                            _context as ITemporaryBlogSettingsDetectionContext;
                        Debug.Assert(tempContext != null,
                                     "IncludeImageEndpoints=true but non-temporary context (type " +
                                     _context.GetType().Name + ") was used");
                        if (tempContext != null)
                        {
                            tempContext.AvailableImageEndpoints = null;
                            try
                            {
                                BlogInfo[] imageEndpoints = blogClient.GetImageEndpoints();
                                tempContext.AvailableImageEndpoints = imageEndpoints;
                                Debug.WriteLine(imageEndpoints.Length + " image endpoints detected");
                            }
                            catch (NotImplementedException)
                            {
                                Debug.WriteLine("Image endpoints not implemented");
                            }
                            catch (Exception e)
                            {
                                Trace.Fail("Exception detecting image endpoints: " + e.ToString());
                            }
                        }
                    }
                }
                // completed
                progressHost.UpdateProgress(100, 100, Res.Get(StringId.ProgressCompletedSettingsDetection));
            }

            return this;
        }
        protected override object DetectBlogService(IProgressHost progressHost)
        {
            using (BlogClientUIContextSilentMode uiContextScope = new BlogClientUIContextSilentMode()) //supress prompting for credentials
            {
                try
                {
                    // copy basic account info
                    IBlogProvider provider = BlogProviderManager.FindProvider("4AA58E69-8C24-40b1-BACE-3BB14237E8F9");
                    _providerId = provider.Id;
                    _serviceName = provider.Name;
                    _clientType = provider.ClientType;

                    //calculate the API url based on the homepage Url.
                    //  API URL Format: <blogurl>/_layouts/metaweblog.aspx
                    string homepagePath = UrlHelper.SafeToAbsoluteUri(new Uri(_homepageUrl)).Split('?')[0];
                    if (homepagePath == null)
                        homepagePath = "/";

                    //trim off any file information included in the URL (ex: /default.aspx)
                    int lastPathPartIndex = homepagePath.LastIndexOf("/", StringComparison.OrdinalIgnoreCase);
                    if (lastPathPartIndex != -1)
                    {
                        string lastPathPart = homepagePath.Substring(lastPathPartIndex);
                        if (lastPathPart.IndexOf('.') != -1)
                        {
                            homepagePath = homepagePath.Substring(0, lastPathPartIndex);
                            if (homepagePath == String.Empty)
                                homepagePath = "/";
                        }
                    }
                    if (homepagePath != "/" && homepagePath.EndsWith("/", StringComparison.OrdinalIgnoreCase)) //trim off trailing slash
                        homepagePath = homepagePath.Substring(0, homepagePath.Length - 1);

                    //Update the homepage url
                    _homepageUrl = homepagePath;

                    _postApiUrl = String.Format(CultureInfo.InvariantCulture, "{0}/_layouts/metaweblog.aspx", homepagePath);

                    if (VerifyCredentialsAndDetectAuthScheme(_postApiUrl, _blogCredentials, _credentials))
                    {
                        AuthenticationErrorOccurred = false;
                        //detect the user's blog ID.
                        if (!BlogProviderParameters.UrlContainsParameters(_postApiUrl))
                        {
                            // we detected the provider, now see if we can detect the weblog id
                            // (or at lease the list of the user's weblogs)
                            UpdateProgress(progressHost, 80, Res.Get(StringId.ProgressAnalyzingWeblogList));
                            AttemptUserBlogDetection();
                        }
                    }
                    else
                        AuthenticationErrorOccurred = true;
                }
                catch (OperationCancelledException)
                {
                    // WasCancelled == true
                }
                catch (BlogClientOperationCancelledException)
                {
                    Cancel();
                    // WasCancelled == true
                }
                catch (BlogAccountDetectorException)
                {
                    // ErrorOccurred == true
                }
                catch (BlogClientAuthenticationException)
                {
                    AuthenticationErrorOccurred = true;
                    // ErrorOccurred == true
                }
                catch (Exception ex)
                {
                    // ErrorOccurred == true
                    ReportError(MessageId.WeblogDetectionUnexpectedError, ex.Message);
                }
            }
            return this;
        }
        private object DetectWeblogSettings(IProgressHost progressHost)
        {
            using (BlogClientUIContextScope uiContextScope = new BlogClientUIContextScope(_uiContext))
            {
                try
                {
                    BlogSettingsDetector blogSettingsDetector = new BlogSettingsDetector(_temporarySettings);
                    blogSettingsDetector.DetectSettings(progressHost);
                }
                catch (OperationCancelledException)
                {
                    // WasCancelled == true
                }
                catch (BlogClientOperationCancelledException)
                {
                    _hostOperation.Cancel();
                    // WasCancelled == true
                }
                catch (Exception ex)
                {
                    Trace.Fail("Error occurred while downloading weblog posts and  categories: " + ex.ToString());
                }

                return this;
            }
        }
        public object DownloadFromUrl(IProgressHost progressHost)
        {
            this.progressHost = progressHost;
            try
            {
                HookEvents();
                DownloadIsComplete = false;
                browserControl.Navigate(Url, false, null, PostData);
            }
            catch
            {

                UnHookEvents(false);
                throw;
            }
            return this;
        }