private BlogAccountFromRsdServiceDescription(RsdServiceDescription rsdServiceDescription) { // look for supported apis from highest fidelity to lowest RsdApi rsdApi = rsdServiceDescription.ScanForApi("WordPress"); if (rsdApi == null) { rsdApi = rsdServiceDescription.ScanForApi("MovableType"); } if (rsdApi == null) { rsdApi = rsdServiceDescription.ScanForApi("MetaWeblog"); } if (rsdApi != null) { Init(rsdServiceDescription.EngineName, rsdApi.Name, rsdApi.ApiLink, rsdApi.BlogId); return; } else { // couldn't find a supported api type so we fall through to here throw new NoSupportedRsdClientTypeException(); } }
private BlogAccount ScanForSupportedRsdApi(RsdServiceDescription rsdServiceDescription) { // initialize client type mappings (including mapping "implied" from ClientType itself ArrayList rsdClientTypeMappings = new ArrayList(_rsdClientTypeMappings); rsdClientTypeMappings.Add(new RsdClientTypeMapping(ClientType, ClientType)); // scan for a match foreach (RsdClientTypeMapping mapping in rsdClientTypeMappings) { RsdApi rsdApi = rsdServiceDescription.ScanForApi(mapping.RsdClientType); if (rsdApi != null) { // HACK: the internal spaces.msn-int site has a bug that causes it to return // the production API URL, so force storage.msn.com to storage.msn-int.com string postApiUrl = rsdApi.ApiLink; if (rsdServiceDescription.HomepageLink.IndexOf("msn-int", StringComparison.OrdinalIgnoreCase) != -1) { postApiUrl = postApiUrl.Replace("storage.msn.com", "storage.msn-int.com"); } return(new BlogAccount(Name, mapping.ClientType, postApiUrl, rsdApi.BlogId)); } } // no match return(null); }
public static BlogAccount Create(RsdServiceDescription rsdServiceDescription) { try { return(new BlogAccountFromRsdServiceDescription(rsdServiceDescription)); } catch (NoSupportedRsdClientTypeException) { return(null); } }
virtual public BlogAccount DetectAccountFromRsdEngineName(RsdServiceDescription rsdServiceDescription) { if (IsMatch(RsdEngineNameRegex, rsdServiceDescription.EngineName)) { return(ScanForSupportedRsdApi(rsdServiceDescription)); } else { return(null); } }
virtual public BlogAccount DetectAccountFromRsdHomepageLink(RsdServiceDescription rsdServiceDescription) { if (IsMatch(RsdHomepageLinkRegex, rsdServiceDescription.HomepageLink)) { return(ScanForSupportedRsdApi(rsdServiceDescription)); } else { return(null); } }
/// <summary> /// Read the definition of a blog service from the passed RSD XML /// </summary> /// <param name="rsdStream"></param> /// <returns></returns> private static async Task <RsdServiceDescription> ReadFromRsdStream(Stream rsdStream, string url) { // initialize a blog service to return RsdServiceDescription rsdServiceDescription = new RsdServiceDescription(); rsdServiceDescription.SourceUrl = url; ArrayList blogApis = new ArrayList(); try { // liberally parse the RSD xml XmlReader reader = XmlReader.Create(rsdStream, new XmlReaderSettings() { Async = true }); //SkipLeadingWhitespace(new StreamReader(rsdStream, new UTF8Encoding(false, false))) ) ; while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { // windows-live writer extensions to rsd if (UrlHelper.UrlsAreEqual(reader.NamespaceURI, WINDOWS_LIVE_WRITER_NAMESPACE)) { /* * switch ( reader.LocalName.ToLower() ) * { * case "manifestlink": * rsdServiceDescription.WriterManifestUrl = reader.ReadString().Trim() ; * break; * } */ } // standard rsd elements else { switch (reader.LocalName.ToUpperInvariant()) { case "ENGINENAME": rsdServiceDescription.EngineName = (await reader.ReadElementContentAsStringAsync()).Trim(); break; case "ENGINELINK": rsdServiceDescription.EngineLink = ToAbsoluteUrl(url, (await reader.ReadElementContentAsStringAsync()).Trim()); break; case "HOMEPAGELINK": rsdServiceDescription.HomepageLink = ToAbsoluteUrl(url, (await reader.ReadElementContentAsStringAsync()).Trim()); break; case "API": RsdApi api = new RsdApi(); for (int i = 0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); switch (reader.LocalName.ToUpperInvariant()) { case "NAME": api.Name = NormalizeApiName(reader.Value); break; case "PREFERRED": api.Preferred = "true" == reader.Value.Trim(); break; case "APILINK": case "RPCLINK": // radio-userland uses rpcLink api.ApiLink = ToAbsoluteUrl(url, reader.Value.Trim()); break; case "BLOGID": api.BlogId = reader.Value.Trim(); break; } } blogApis.Add(api); break; case "SETTING": if (blogApis.Count > 0) { RsdApi lastRsdApi = (RsdApi)blogApis[blogApis.Count - 1]; string name = reader.GetAttribute("name"); if (name != null) { string value = (await reader.ReadContentAsStringAsync()).Trim(); lastRsdApi.Settings.Add(name, value); } } break; } } } } } catch (Exception ex) { //Trace.Fail("Exception attempting to read RSD file: " + ex.ToString()) ; // don't re-propagate exceptions here becaus we found that TypePad's // RSD file was returning bogus HTTP crap at the end of the response // and the XML parser cholking on this caused us to fail autodetection } // if we got at least one API then return the service description if (blogApis.Count > 0) { rsdServiceDescription.Apis = (RsdApi[])blogApis.ToArray(typeof(RsdApi)); return(rsdServiceDescription); } else { return(null); } }
protected override object DetectBlogService(IProgressHost progressHost) { using (BlogClientUIContextSilentMode uiContextScope = new BlogClientUIContextSilentMode()) //suppress 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); } }
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); } }
public override async Task <object> DetectBlogService(IProgressHost progressHost, IEnumerable <IBlogProvider> availableProviders) { //using ( BlogClientUIContextSilentMode uiContextScope = new BlogClientUIContextSilentMode() ) //supress prompting for credentials //{ try { // get the weblog homepage and rsd service description if available var weblogDOM = await 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?.Body; bool detectionSucceeded = false; if (!detectionSucceeded) { detectionSucceeded = AttemptGenericAtomLinkDetection(_homepageUrl, html, !ApplicationDiagnostics.PreferAtom); } if (!detectionSucceeded) { detectionSucceeded = await AttemptBloggerDetection(_homepageUrl, html); } if (!detectionSucceeded) { RsdServiceDescription rsdServiceDescription = await 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 detectionSucceeded = await AttemptRsdBasedDetection(progressHost, rsdServiceDescription, availableProviders); if (!detectionSucceeded) { // try detection by analyzing the homepage url and contents UpdateProgress(progressHost, 75, "Analysing homepage..."); if (weblogDOM != null) { detectionSucceeded = AttemptHomepageBasedDetection(_homepageUrl, html, availableProviders); } else { detectionSucceeded = AttemptUrlBasedDetection(_homepageUrl, availableProviders); } // 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, "Analysing weblog list"); await AttemptUserBlogDetectionAsync(); } } } } 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); //} }