PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/BlogEngine/DotNetSlave.BusinessLogic/Web/HttpHandlers/Sioc.cs

#
C# | 707 lines | 391 code | 102 blank | 214 comment | 30 complexity | 0050623c1403cb623aeb18e8282a96bb MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. namespace BlogEngine.Core.Web.HttpHandlers
  2. {
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Security.Cryptography;
  8. using System.Text;
  9. using System.Text.RegularExpressions;
  10. using System.Web;
  11. using System.Web.Security;
  12. using System.Xml;
  13. /// <summary>
  14. /// Based on John Dyer's (http://johndyer.name/) extension.
  15. /// </summary>
  16. public class Sioc : IHttpHandler
  17. {
  18. #region Constants and Fields
  19. /// <summary>
  20. /// The xml namespaces.
  21. /// </summary>
  22. private static Dictionary<string, string> xmlNamespaces;
  23. #endregion
  24. #region Properties
  25. /// <summary>
  26. /// Gets a value indicating whether another request can use the <see cref = "T:System.Web.IHttpHandler"></see> instance.
  27. /// </summary>
  28. /// <value></value>
  29. /// <returns>true if the <see cref = "T:System.Web.IHttpHandler"></see> instance is reusable; otherwise, false.</returns>
  30. public bool IsReusable
  31. {
  32. get
  33. {
  34. return false;
  35. }
  36. }
  37. /// <summary>
  38. /// Gets SupportedNamespaces.
  39. /// </summary>
  40. private static Dictionary<string, string> SupportedNamespaces
  41. {
  42. get
  43. {
  44. return xmlNamespaces ??
  45. (xmlNamespaces =
  46. new Dictionary<string, string>
  47. {
  48. { "foaf", "http://xmlns.com/foaf/0.1/" },
  49. { "rss", "http://purl.org/rss/1.0/" },
  50. { "admin", "http://webns.net/mvcb/" },
  51. { "dc", "http://purl.org/dc/elements/1.1/" },
  52. { "dcterms", "http://purl.org/dc/terms/" },
  53. { "rdfs", "http://www.w3.org/2000/01/rdf-schema#" },
  54. { "rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#" },
  55. { "content", "http://purl.org/rss/1.0/modules/content" },
  56. { "sioc", "http://rdfs.org/sioc/ns#" }
  57. });
  58. }
  59. }
  60. #endregion
  61. #region Implemented Interfaces
  62. #region IHttpHandler
  63. /// <summary>
  64. /// Enables processing of HTTP Web requests by a custom HttpHandler that implements the <see cref="T:System.Web.IHttpHandler"></see> interface.
  65. /// </summary>
  66. /// <param name="context">
  67. /// An <see cref="T:System.Web.HttpContext"></see> object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests.
  68. /// </param>
  69. public void ProcessRequest(HttpContext context)
  70. {
  71. context.Response.ContentType = "text/xml";
  72. var siocType = context.Request["sioc_type"] + string.Empty;
  73. var siocId = context.Request["sioc_id"] + string.Empty;
  74. switch (siocType)
  75. {
  76. default:
  77. // case "site":
  78. var list = Post.Posts.ConvertAll(ConvertToIPublishable);
  79. var max = Math.Min(BlogSettings.Instance.PostsPerFeed, list.Count);
  80. list = list.GetRange(0, max);
  81. WriteSite(context.Response.OutputStream, list);
  82. break;
  83. case "post":
  84. Guid postId;
  85. if (siocId.TryParse(out postId))
  86. {
  87. var post = Post.GetPost(postId);
  88. if (post != null)
  89. {
  90. WritePub(context.Response.OutputStream, post);
  91. }
  92. }
  93. break;
  94. case "comment":
  95. Guid commentId;
  96. if (siocId.TryParse(out commentId))
  97. {
  98. // TODO: is it possible to get a single comment?
  99. var comment = GetComment(commentId);
  100. if (comment != null)
  101. {
  102. WritePub(context.Response.OutputStream, comment);
  103. }
  104. }
  105. break;
  106. case "user":
  107. WriteAuthor(context.Response.OutputStream, siocId);
  108. break;
  109. /*
  110. case "post":
  111. generator.WriteSite(context.Response.OutputStream);
  112. break;
  113. */
  114. }
  115. }
  116. #endregion
  117. #endregion
  118. #region Methods
  119. /// <summary>
  120. /// Calculates the SHA1.
  121. /// </summary>
  122. /// <param name="text">
  123. /// The text string.
  124. /// </param>
  125. /// <param name="enc">
  126. /// The encoding.
  127. /// </param>
  128. /// <returns>
  129. /// The hash string.
  130. /// </returns>
  131. private static string CalculateSha1(string text, Encoding enc)
  132. {
  133. var buffer = enc.GetBytes(text);
  134. var cryptoTransformSha1 = new SHA1CryptoServiceProvider();
  135. var hash = BitConverter.ToString(cryptoTransformSha1.ComputeHash(buffer)).Replace("-", string.Empty);
  136. return hash.ToLower();
  137. }
  138. /// <summary>
  139. /// Closes the writer.
  140. /// </summary>
  141. /// <param name="xmlWriter">
  142. /// The XML writer.
  143. /// </param>
  144. private static void CloseWriter(XmlWriter xmlWriter)
  145. {
  146. xmlWriter.WriteEndElement(); // rdf:RDF
  147. xmlWriter.WriteEndDocument();
  148. xmlWriter.Close();
  149. }
  150. /// <summary>
  151. /// Converts to publishable interface.
  152. /// </summary>
  153. /// <param name="item">
  154. /// The publishable item.
  155. /// </param>
  156. /// <returns>
  157. /// The publishable interface.
  158. /// </returns>
  159. private static IPublishable ConvertToIPublishable(IPublishable item)
  160. {
  161. return item;
  162. }
  163. /// <summary>
  164. /// Gets the blog author URL.
  165. /// </summary>
  166. /// <param name="username">
  167. /// The username.
  168. /// </param>
  169. /// <returns>
  170. /// Blog author url.
  171. /// </returns>
  172. private static string GetBlogAuthorUrl(string username)
  173. {
  174. return string.Format("{0}author/{1}.aspx", Utils.AbsoluteWebRoot, HttpUtility.UrlEncode(username));
  175. }
  176. /// <summary>
  177. /// Gets the comment.
  178. /// </summary>
  179. /// <param name="commentId">
  180. /// The comment id.
  181. /// </param>
  182. /// <returns>
  183. /// The comment.
  184. /// </returns>
  185. private static Comment GetComment(Guid commentId)
  186. {
  187. var posts = Post.Posts;
  188. return posts.SelectMany(post => post.Comments).FirstOrDefault(comm => comm.Id == commentId);
  189. }
  190. /// <summary>
  191. /// Gets the sioc author URL.
  192. /// </summary>
  193. /// <param name="username">
  194. /// The username.
  195. /// </param>
  196. /// <returns>
  197. /// The SIOC Author Url.
  198. /// </returns>
  199. private static string GetSiocAuthorUrl(string username)
  200. {
  201. return string.Format(
  202. "{0}sioc.axd?sioc_type=user&sioc_id={1}", Utils.AbsoluteWebRoot, HttpUtility.UrlEncode(username));
  203. }
  204. /// <summary>
  205. /// Gets the sioc authors URL.
  206. /// </summary>
  207. /// <returns>
  208. /// The SIOC Author Url.
  209. /// </returns>
  210. private static string GetSiocAuthorsUrl()
  211. {
  212. return string.Format("{0}sioc.axd?sioc_type=site#authors", Utils.AbsoluteWebRoot);
  213. }
  214. /// <summary>
  215. /// Gets the sioc blog URL.
  216. /// </summary>
  217. /// <returns>
  218. /// The SIOC Blog Url.
  219. /// </returns>
  220. private static string GetSiocBlogUrl()
  221. {
  222. return string.Format("{0}sioc.axd?sioc_type=site#webblog", Utils.AbsoluteWebRoot);
  223. }
  224. /// <summary>
  225. /// Gets the sioc comment URL.
  226. /// </summary>
  227. /// <param name="id">
  228. /// The comment id.
  229. /// </param>
  230. /// <returns>
  231. /// The SIOC Comment Url.
  232. /// </returns>
  233. private static string GetSiocCommentUrl(string id)
  234. {
  235. return string.Format("{0}sioc.axd?sioc_type=comment&sioc_id={1}", Utils.AbsoluteWebRoot, id);
  236. }
  237. /// <summary>
  238. /// Gets the sioc post URL.
  239. /// </summary>
  240. /// <param name="id">
  241. /// The SIOC post id.
  242. /// </param>
  243. /// <returns>
  244. /// The SIOC Post Url.
  245. /// </returns>
  246. private static string GetSiocPostUrl(string id)
  247. {
  248. return string.Format("{0}sioc.axd?sioc_type=post&sioc_id={1}", Utils.AbsoluteWebRoot, id);
  249. }
  250. /*
  251. /// <summary>
  252. /// Gets the sioc site URL.
  253. /// </summary>
  254. /// <returns>
  255. /// The SIOC Site Url.
  256. /// </returns>
  257. private static string GetSiocSiteUrl()
  258. {
  259. return string.Format("{0}sioc.axd?sioc_type=site", Utils.AbsoluteWebRoot);
  260. }
  261. */
  262. /// <summary>
  263. /// Gets the writer.
  264. /// </summary>
  265. /// <param name="stream">
  266. /// The stream.
  267. /// </param>
  268. /// <returns>
  269. /// The Xml Writer.
  270. /// </returns>
  271. private static XmlWriter GetWriter(Stream stream)
  272. {
  273. var settings = new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true };
  274. var xmlWriter = XmlWriter.Create(stream, settings);
  275. xmlWriter.WriteStartDocument();
  276. xmlWriter.WriteStartElement("rdf", "RDF", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
  277. // "http://xmlns.com/foaf/0.1/");
  278. foreach (var prefix in SupportedNamespaces.Keys)
  279. {
  280. xmlWriter.WriteAttributeString("xmlns", prefix, null, SupportedNamespaces[prefix]);
  281. }
  282. return xmlWriter;
  283. }
  284. /// <summary>
  285. /// Writes the author.
  286. /// </summary>
  287. /// <param name="stream">
  288. /// The stream.
  289. /// </param>
  290. /// <param name="authorName">
  291. /// Name of the author.
  292. /// </param>
  293. private static void WriteAuthor(Stream stream, string authorName)
  294. {
  295. var xmlWriter = GetWriter(stream);
  296. WriteFoafDocument(xmlWriter, "user", GetSiocAuthorUrl(authorName));
  297. var user = Membership.GetUser(authorName);
  298. var ap = AuthorProfile.GetProfile(authorName);
  299. // FOAF:Person
  300. xmlWriter.WriteStartElement("foaf", "Person", null);
  301. xmlWriter.WriteAttributeString("rdf", "about", null, GetSiocAuthorUrl(authorName));
  302. xmlWriter.WriteElementString("foaf", "Name", null, authorName);
  303. if (ap != null && !ap.Private && ap.FirstName != String.Empty)
  304. {
  305. xmlWriter.WriteElementString("foaf", "firstName", null, ap.FirstName);
  306. }
  307. if (ap != null && !ap.Private && ap.LastName != String.Empty)
  308. {
  309. xmlWriter.WriteElementString("foaf", "surname", null, ap.LastName);
  310. }
  311. xmlWriter.WriteElementString(
  312. "foaf", "mbox_sha1sum", null, (user != null) ? CalculateSha1(user.Email, Encoding.UTF8) : string.Empty);
  313. xmlWriter.WriteStartElement("foaf", "homepage", null);
  314. xmlWriter.WriteAttributeString("rdf", "resource", null, Utils.AbsoluteWebRoot.ToString());
  315. xmlWriter.WriteEndElement(); // foaf:homepage
  316. xmlWriter.WriteStartElement("foaf", "holdsAccount", null);
  317. xmlWriter.WriteAttributeString("rdf", "resource", null, GetBlogAuthorUrl(authorName));
  318. xmlWriter.WriteEndElement(); // foaf:holdsAccount
  319. xmlWriter.WriteEndElement(); // foaf:Person
  320. // SIOC:User
  321. xmlWriter.WriteStartElement("sioc", "User", null);
  322. xmlWriter.WriteAttributeString("rdf", "about", null, GetBlogAuthorUrl(authorName));
  323. xmlWriter.WriteElementString("foaf", "accountName", null, authorName);
  324. xmlWriter.WriteElementString("sioc", "name", null, authorName);
  325. // xmlWriter.WriteElementString("dcterms", "created", null, "TODO:" + authorName);
  326. xmlWriter.WriteEndElement(); // sioc:User
  327. CloseWriter(xmlWriter);
  328. }
  329. /// <summary>
  330. /// Writes the foaf document.
  331. /// </summary>
  332. /// <param name="xmlWriter">
  333. /// The XML writer.
  334. /// </param>
  335. /// <param name="siocType">
  336. /// Type of the sioc.
  337. /// </param>
  338. /// <param name="url">
  339. /// The URL string.
  340. /// </param>
  341. private static void WriteFoafDocument(XmlWriter xmlWriter, string siocType, string url)
  342. {
  343. var title = string.Format("SIOC {0} profile for \"{1}\"", siocType, BlogSettings.Instance.Name);
  344. const string Description =
  345. "A SIOC profile describes the structure and contents of a weblog in a machine readable form. For more information please refer to http://sioc-project.org/.";
  346. xmlWriter.WriteStartElement("foaf", "Document", null);
  347. xmlWriter.WriteAttributeString("rdf", "about", null, Utils.AbsoluteWebRoot.ToString());
  348. xmlWriter.WriteElementString("dc", "title", null, title);
  349. xmlWriter.WriteElementString("dc", "description", null, Description);
  350. xmlWriter.WriteElementString("foaf", "primaryTopic", null, url);
  351. xmlWriter.WriteElementString(
  352. "admin", "generatorAgent", null, string.Format("BlogEngine.NET{0}", BlogSettings.Instance.Version()));
  353. xmlWriter.WriteEndElement(); // foaf:Document
  354. }
  355. /// <summary>
  356. /// Writes the forum.
  357. /// </summary>
  358. /// <param name="xmlWriter">
  359. /// The xml writer.
  360. /// </param>
  361. /// <param name="list">
  362. /// The enumerable of publishable interface.
  363. /// </param>
  364. private static void WriteForum(XmlWriter xmlWriter, IEnumerable<IPublishable> list)
  365. {
  366. xmlWriter.WriteStartElement("sioc", "Forum", null);
  367. xmlWriter.WriteAttributeString("rdf", "about", null, GetSiocBlogUrl());
  368. xmlWriter.WriteElementString("sioc", "name", null, BlogSettings.Instance.Name);
  369. xmlWriter.WriteStartElement("sioc", "link", null);
  370. xmlWriter.WriteAttributeString("rdf", "resource", null, GetSiocBlogUrl());
  371. xmlWriter.WriteEndElement();
  372. foreach (var pub in list)
  373. {
  374. xmlWriter.WriteStartElement("sioc", "container_of", null);
  375. xmlWriter.WriteStartElement("sioc", "Post", null);
  376. xmlWriter.WriteAttributeString("rdf", "about", null, pub.AbsoluteLink.ToString());
  377. xmlWriter.WriteAttributeString("dc", "title", null, pub.Title);
  378. xmlWriter.WriteStartElement("rdfs", "seeAlso", null);
  379. xmlWriter.WriteAttributeString("rdf", "resource", null, GetSiocPostUrl(pub.Id.ToString()));
  380. xmlWriter.WriteEndElement(); // sioc:Post
  381. xmlWriter.WriteEndElement(); // sioc:Post
  382. xmlWriter.WriteEndElement(); // sioc:Forum
  383. }
  384. xmlWriter.WriteEndElement(); // sioc:Forum
  385. }
  386. /// <summary>
  387. /// Writes an IPublishable to a stream.
  388. /// </summary>
  389. /// <param name="stream">
  390. /// The stream.
  391. /// </param>
  392. /// <param name="pub">
  393. /// The publishable interface.
  394. /// </param>
  395. private static void WritePub(Stream stream, IPublishable pub)
  396. {
  397. var xmlWriter = GetWriter(stream);
  398. if (pub is Post)
  399. {
  400. WriteFoafDocument(xmlWriter, "post", pub.AbsoluteLink.ToString());
  401. }
  402. else
  403. {
  404. WriteFoafDocument(xmlWriter, "comment", pub.AbsoluteLink.ToString());
  405. }
  406. WriteSiocPost(xmlWriter, pub);
  407. CloseWriter(xmlWriter);
  408. }
  409. /// <summary>
  410. /// Writes SIOC post.
  411. /// </summary>
  412. /// <param name="xmlWriter">
  413. /// The xml writer.
  414. /// </param>
  415. /// <param name="pub">
  416. /// The publishable interface.
  417. /// </param>
  418. private static void WriteSiocPost(XmlWriter xmlWriter, IPublishable pub)
  419. {
  420. xmlWriter.WriteStartElement("sioc", "Post", null);
  421. xmlWriter.WriteAttributeString("rdf", "about", null, pub.AbsoluteLink.ToString());
  422. xmlWriter.WriteStartElement("sioc", "link", null);
  423. xmlWriter.WriteAttributeString("rdf", "resource", null, pub.AbsoluteLink.ToString());
  424. xmlWriter.WriteEndElement(); // sioc:link
  425. xmlWriter.WriteStartElement("sioc", "has_container", null);
  426. xmlWriter.WriteAttributeString("rdf", "resource", null, GetSiocBlogUrl());
  427. xmlWriter.WriteEndElement(); // sioc:has_container
  428. xmlWriter.WriteElementString("dc", "title", null, pub.Title);
  429. // SIOC:USER
  430. if (pub is Post)
  431. {
  432. xmlWriter.WriteStartElement("sioc", "has_creator", null);
  433. xmlWriter.WriteStartElement("sioc", "User", null);
  434. xmlWriter.WriteAttributeString("rdf", "about", null, GetBlogAuthorUrl(pub.Author));
  435. xmlWriter.WriteStartElement("rdfs", "seeAlso", null);
  436. xmlWriter.WriteAttributeString("rdf", "resource", null, GetSiocAuthorUrl(pub.Author));
  437. xmlWriter.WriteEndElement(); // rdf:about
  438. xmlWriter.WriteEndElement(); // sioc:User
  439. xmlWriter.WriteEndElement(); // sioc:has_creator
  440. }
  441. // FOAF:maker
  442. xmlWriter.WriteStartElement("foaf", "maker", null);
  443. xmlWriter.WriteStartElement("foaf", "Person", null);
  444. if (pub is Post)
  445. {
  446. xmlWriter.WriteAttributeString("rdf", "about", null, GetBlogAuthorUrl(pub.Author));
  447. }
  448. xmlWriter.WriteAttributeString("foaf", "name", null, pub.Author);
  449. if (pub is Post)
  450. {
  451. var user = Membership.GetUser(pub.Author);
  452. xmlWriter.WriteElementString(
  453. "foaf",
  454. "mbox_sha1sum",
  455. null,
  456. (user != null) ? CalculateSha1(user.Email, Encoding.UTF8) : string.Empty);
  457. }
  458. else
  459. {
  460. xmlWriter.WriteElementString(
  461. "foaf", "mbox_sha1sum", null, CalculateSha1(((Comment)pub).Email, Encoding.UTF8));
  462. }
  463. xmlWriter.WriteStartElement("foaf", "homepage", null);
  464. if (pub is Post)
  465. {
  466. xmlWriter.WriteAttributeString("rdf", "resource", null, Utils.AbsoluteWebRoot.ToString());
  467. }
  468. else
  469. {
  470. xmlWriter.WriteAttributeString("rdf", "resource", null, "TODO:");
  471. }
  472. xmlWriter.WriteEndElement(); // foaf:homepage
  473. if (pub is Post)
  474. {
  475. xmlWriter.WriteStartElement("rdfs", "seeAlso", null);
  476. xmlWriter.WriteAttributeString("rdf", "resource", null, GetSiocAuthorUrl(pub.Author));
  477. xmlWriter.WriteEndElement(); // rdfs:seeAlso
  478. }
  479. xmlWriter.WriteEndElement(); // foaf:Person
  480. xmlWriter.WriteEndElement(); // foaf:maker
  481. // CONTENT
  482. // xmlWriter.WriteElementString("dcterms", "created", null, DpUtility.ToW3cDateTime(pub.DateCreated));
  483. xmlWriter.WriteElementString("sioc", "content", null, Utils.StripHtml(pub.Content));
  484. xmlWriter.WriteElementString("content", "encoded", null, pub.Content);
  485. // TOPICS
  486. if (pub is Post)
  487. {
  488. // categories
  489. foreach (var category in ((Post)pub).Categories)
  490. {
  491. xmlWriter.WriteStartElement("sioc", "topic", null);
  492. xmlWriter.WriteAttributeString("rdfs", "label", null, category.Title);
  493. xmlWriter.WriteAttributeString("rdf", "resource", null, category.AbsoluteLink.ToString());
  494. xmlWriter.WriteEndElement(); // sioc:topic
  495. }
  496. // tags are also supposed to be treated as sioc:topic
  497. foreach (var tag in ((Post)pub).Tags)
  498. {
  499. xmlWriter.WriteStartElement("sioc", "topic", null);
  500. xmlWriter.WriteAttributeString("rdfs", "label", null, tag);
  501. xmlWriter.WriteAttributeString("rdf", "resource", null, Utils.AbsoluteWebRoot + "?tag=/" + tag);
  502. xmlWriter.WriteEndElement(); // sioc:topic
  503. }
  504. // COMMENTS
  505. foreach (var comment in ((Post)pub).ApprovedComments)
  506. {
  507. xmlWriter.WriteStartElement("sioc", "has_reply", null);
  508. xmlWriter.WriteStartElement("sioc", "Post", null);
  509. xmlWriter.WriteAttributeString("rdf", "about", null, comment.AbsoluteLink.ToString());
  510. xmlWriter.WriteStartElement("rdfs", "seeAlso", null);
  511. xmlWriter.WriteAttributeString("rdf", "resource", null, GetSiocCommentUrl(comment.Id.ToString()));
  512. xmlWriter.WriteEndElement(); // rdfs:seeAlso
  513. xmlWriter.WriteEndElement(); // sioc:Post
  514. xmlWriter.WriteEndElement(); // sioc:has_reply
  515. }
  516. // TODO: LINKS
  517. var linkMatches = Regex.Matches(pub.Content, @"<a[^(href)]?href=""([^""]+)""[^>]?>([^<]+)</a>");
  518. var linkPairs = new List<string>();
  519. foreach (Match linkMatch in linkMatches)
  520. {
  521. var url = linkMatch.Groups[1].Value;
  522. var text = linkMatch.Groups[2].Value;
  523. if (url.IndexOf(Utils.AbsoluteWebRoot.ToString()) == 0)
  524. {
  525. continue;
  526. }
  527. var pair = url + "|" + text;
  528. if (linkPairs.Contains(pair))
  529. {
  530. continue;
  531. }
  532. xmlWriter.WriteStartElement("sioc", "links_to", null);
  533. xmlWriter.WriteAttributeString("rdf", "resource", null, url);
  534. xmlWriter.WriteAttributeString("rdfs", "label", null, text);
  535. xmlWriter.WriteEndElement(); // sioc:links_to
  536. linkPairs.Add(pair);
  537. }
  538. }
  539. xmlWriter.WriteEndElement(); // sioc:Post
  540. }
  541. /// <summary>
  542. /// Writes sioc site.
  543. /// </summary>
  544. /// <param name="xmlWriter">
  545. /// The xml writer.
  546. /// </param>
  547. private static void WriteSiocSite(XmlWriter xmlWriter)
  548. {
  549. xmlWriter.WriteStartElement("sioc", "Site", null);
  550. xmlWriter.WriteAttributeString("rdf", "about", null, Utils.AbsoluteWebRoot.ToString());
  551. xmlWriter.WriteElementString("dc", "title", null, BlogSettings.Instance.Name);
  552. xmlWriter.WriteElementString("dc", "description", null, BlogSettings.Instance.Description);
  553. xmlWriter.WriteElementString("sioc", "link", null, Utils.AbsoluteWebRoot.ToString());
  554. xmlWriter.WriteElementString("sioc", "host_of", null, GetSiocBlogUrl());
  555. xmlWriter.WriteElementString("sioc", "has_group", null, GetSiocAuthorsUrl());
  556. xmlWriter.WriteEndElement(); // sioc:Site
  557. }
  558. /// <summary>
  559. /// Writes site.
  560. /// </summary>
  561. /// <param name="stream">
  562. /// The stream.
  563. /// </param>
  564. /// <param name="list">
  565. /// The enumerable of IPublishable.
  566. /// </param>
  567. private static void WriteSite(Stream stream, IEnumerable<IPublishable> list)
  568. {
  569. var xmlWriter = GetWriter(stream);
  570. WriteUserGroup(xmlWriter);
  571. WriteFoafDocument(xmlWriter, "site", Utils.AbsoluteWebRoot.ToString());
  572. WriteSiocSite(xmlWriter);
  573. WriteForum(xmlWriter, list);
  574. CloseWriter(xmlWriter);
  575. }
  576. /// <summary>
  577. /// Writes the user group.
  578. /// </summary>
  579. /// <param name="xmlWriter">
  580. /// The XML writer.
  581. /// </param>
  582. private static void WriteUserGroup(XmlWriter xmlWriter)
  583. {
  584. xmlWriter.WriteStartElement("sioc", "Usergroup", null);
  585. xmlWriter.WriteAttributeString("rdf", "about", null, GetSiocAuthorsUrl());
  586. xmlWriter.WriteElementString("dc", "title", null, "Authors at \"" + BlogSettings.Instance.Name + "\"");
  587. int count;
  588. var members = Membership.Provider.GetAllUsers(0, 999, out count);
  589. foreach (MembershipUser user in members)
  590. {
  591. xmlWriter.WriteStartElement("sioc", "has_member", null);
  592. xmlWriter.WriteStartElement("sioc", "User", null);
  593. xmlWriter.WriteAttributeString("rdf", "about", null, GetBlogAuthorUrl(user.UserName));
  594. xmlWriter.WriteAttributeString("rdfs", "label", null, user.UserName);
  595. xmlWriter.WriteStartElement("sioc", "see_also", null);
  596. xmlWriter.WriteAttributeString("rdf", "resource", null, GetSiocAuthorUrl(user.UserName));
  597. xmlWriter.WriteEndElement(); // sioc:see_also
  598. xmlWriter.WriteEndElement(); // sioc:User
  599. xmlWriter.WriteEndElement(); // sioc:has_member
  600. }
  601. xmlWriter.WriteEndElement(); // foaf:Document
  602. }
  603. #endregion
  604. }
  605. }