PageRenderTime 50ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/BlogEngine/DotNetSlave.BusinessLogic/Providers/XmlProvider/Posts.cs

#
C# | 377 lines | 259 code | 58 blank | 60 comment | 42 complexity | e2ef41226b644913c292860a6a531aea MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. namespace BlogEngine.Core.Providers
  2. {
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Globalization;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Web;
  9. using System.Xml;
  10. /// <summary>
  11. /// A storage provider for BlogEngine that uses XML files.
  12. /// <remarks>
  13. /// To build another provider, you can just copy and modify
  14. /// this one. Then add it to the web.config's BlogEngine section.
  15. /// </remarks>
  16. /// </summary>
  17. public partial class XmlBlogProvider : BlogProvider
  18. {
  19. // private static string _Folder = System.Web.HttpContext.Current.Server.MapPath(BlogSettings.Instance.StorageLocation);
  20. #region Properties
  21. /// <summary>
  22. /// Gets the storage folder of the current blog instance.
  23. /// </summary>
  24. internal string Folder
  25. {
  26. get
  27. {
  28. return GetFolder(Blog.CurrentInstance);
  29. }
  30. }
  31. /// <summary>
  32. /// Gets the storage folder for the blog.
  33. /// </summary>
  34. internal string GetFolder(Blog blog)
  35. {
  36. // if "blog" == null, this means it's the primary instance being asked for -- which
  37. // is in the root of BlogConfig.StorageLocation.
  38. string location = blog == null ? BlogConfig.StorageLocation : blog.StorageLocation;
  39. var p = location.Replace("~/", string.Empty);
  40. return Path.Combine(HttpRuntime.AppDomainAppPath, p);
  41. }
  42. #endregion
  43. #region Public Methods
  44. /// <summary>
  45. /// Deletes a post from the data store.
  46. /// </summary>
  47. /// <param name="post">
  48. /// The post to delete.
  49. /// </param>
  50. public override void DeletePost(Post post)
  51. {
  52. var fileName = string.Format("{0}posts{1}{2}.xml", this.Folder, Path.DirectorySeparatorChar, post.Id);
  53. if (File.Exists(fileName))
  54. {
  55. File.Delete(fileName);
  56. }
  57. }
  58. /// <summary>
  59. /// Retrieves all posts from the data store
  60. /// </summary>
  61. /// <returns>
  62. /// List of Posts
  63. /// </returns>
  64. public override List<Post> FillPosts()
  65. {
  66. var folder = this.Folder + "posts" + Path.DirectorySeparatorChar;
  67. var posts = (from file in Directory.GetFiles(folder, "*.xml", SearchOption.TopDirectoryOnly)
  68. select new FileInfo(file)
  69. into info
  70. select info.Name.Replace(".xml", string.Empty)
  71. into id
  72. select Post.Load(new Guid(id))).ToList();
  73. posts.Sort();
  74. return posts;
  75. }
  76. /// <summary>
  77. /// Inserts a new Post to the data store.
  78. /// </summary>
  79. /// <param name="post">
  80. /// The post to insert.
  81. /// </param>
  82. public override void InsertPost(Post post)
  83. {
  84. if (!Directory.Exists(string.Format("{0}posts", this.Folder)))
  85. {
  86. Directory.CreateDirectory(string.Format("{0}posts", this.Folder));
  87. }
  88. var fileName = string.Format("{0}posts{1}{2}.xml", this.Folder, Path.DirectorySeparatorChar, post.Id);
  89. var settings = new XmlWriterSettings { Indent = true };
  90. var ms = new MemoryStream();
  91. using (var writer = XmlWriter.Create(ms, settings))
  92. {
  93. writer.WriteStartDocument(true);
  94. writer.WriteStartElement("post");
  95. writer.WriteElementString("author", post.Author);
  96. writer.WriteElementString("title", post.Title);
  97. writer.WriteElementString("description", post.Description);
  98. writer.WriteElementString("content", post.Content);
  99. writer.WriteElementString("ispublished", post.IsPublished.ToString());
  100. writer.WriteElementString("isdeleted", post.IsDeleted.ToString());
  101. writer.WriteElementString("iscommentsenabled", post.HasCommentsEnabled.ToString());
  102. writer.WriteElementString(
  103. "pubDate",
  104. post.DateCreated.AddHours(-BlogSettings.Instance.Timezone).ToString(
  105. "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture));
  106. writer.WriteElementString(
  107. "lastModified",
  108. post.DateModified.AddHours(-BlogSettings.Instance.Timezone).ToString(
  109. "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture));
  110. writer.WriteElementString("raters", post.Raters.ToString(CultureInfo.InvariantCulture));
  111. writer.WriteElementString("rating", post.Rating.ToString(CultureInfo.InvariantCulture));
  112. writer.WriteElementString("slug", post.Slug);
  113. // Tags
  114. writer.WriteStartElement("tags");
  115. foreach (var tag in post.Tags)
  116. {
  117. writer.WriteElementString("tag", tag);
  118. }
  119. writer.WriteEndElement();
  120. // comments
  121. writer.WriteStartElement("comments");
  122. foreach (var comment in post.AllComments)
  123. {
  124. writer.WriteStartElement("comment");
  125. writer.WriteAttributeString("id", comment.Id.ToString());
  126. writer.WriteAttributeString("parentid", comment.ParentId.ToString());
  127. writer.WriteAttributeString("approved", comment.IsApproved.ToString());
  128. writer.WriteAttributeString("spam", comment.IsSpam.ToString());
  129. writer.WriteAttributeString("deleted", comment.IsDeleted.ToString());
  130. writer.WriteElementString(
  131. "date",
  132. comment.DateCreated.AddHours(-BlogSettings.Instance.Timezone).ToString(
  133. "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture));
  134. writer.WriteElementString("author", comment.Author);
  135. writer.WriteElementString("email", comment.Email);
  136. writer.WriteElementString("country", comment.Country);
  137. writer.WriteElementString("ip", comment.IP);
  138. if (comment.Website != null)
  139. {
  140. writer.WriteElementString("website", comment.Website.ToString());
  141. }
  142. if (!string.IsNullOrEmpty(comment.ModeratedBy))
  143. {
  144. writer.WriteElementString("moderatedby", comment.ModeratedBy);
  145. }
  146. if (comment.Avatar != null)
  147. {
  148. writer.WriteElementString("avatar", comment.Avatar);
  149. }
  150. writer.WriteElementString("content", comment.Content);
  151. writer.WriteEndElement();
  152. }
  153. writer.WriteEndElement();
  154. // categories
  155. writer.WriteStartElement("categories");
  156. foreach (var cat in post.Categories)
  157. {
  158. // if (cat.Id = .Instance.ContainsKey(key))
  159. // writer.WriteElementString("category", key.ToString());
  160. writer.WriteElementString("category", cat.Id.ToString());
  161. }
  162. writer.WriteEndElement();
  163. // Notification e-mails
  164. writer.WriteStartElement("notifications");
  165. foreach (var email in post.NotificationEmails)
  166. {
  167. writer.WriteElementString("email", email);
  168. }
  169. writer.WriteEndElement();
  170. writer.WriteEndElement();
  171. }
  172. using (var fs = File.Open(fileName, FileMode.Create, FileAccess.Write))
  173. {
  174. ms.WriteTo(fs);
  175. ms.Dispose();
  176. }
  177. }
  178. /// <summary>
  179. /// Retrieves a Post from the provider based on the specified id.
  180. /// </summary>
  181. /// <param name="id">
  182. /// The Post id.
  183. /// </param>
  184. /// <returns>
  185. /// A Post object.
  186. /// </returns>
  187. public override Post SelectPost(Guid id)
  188. {
  189. var fileName = string.Format("{0}posts{1}{2}.xml", this.Folder, Path.DirectorySeparatorChar, id);
  190. var post = new Post();
  191. var doc = new XmlDocument();
  192. doc.Load(fileName);
  193. post.Title = doc.SelectSingleNode("post/title").InnerText;
  194. post.Description = doc.SelectSingleNode("post/description").InnerText;
  195. post.Content = doc.SelectSingleNode("post/content").InnerText;
  196. if (doc.SelectSingleNode("post/pubDate") != null)
  197. {
  198. post.DateCreated = DateTime.Parse(
  199. doc.SelectSingleNode("post/pubDate").InnerText, CultureInfo.InvariantCulture);
  200. }
  201. if (doc.SelectSingleNode("post/lastModified") != null)
  202. {
  203. post.DateModified = DateTime.Parse(
  204. doc.SelectSingleNode("post/lastModified").InnerText, CultureInfo.InvariantCulture);
  205. }
  206. if (doc.SelectSingleNode("post/author") != null)
  207. {
  208. post.Author = doc.SelectSingleNode("post/author").InnerText;
  209. }
  210. if (doc.SelectSingleNode("post/ispublished") != null)
  211. {
  212. post.IsPublished = bool.Parse(doc.SelectSingleNode("post/ispublished").InnerText);
  213. }
  214. if (doc.SelectSingleNode("post/isdeleted") != null)
  215. {
  216. post.IsDeleted = bool.Parse(doc.SelectSingleNode("post/isdeleted").InnerText);
  217. }
  218. if (doc.SelectSingleNode("post/iscommentsenabled") != null)
  219. {
  220. post.HasCommentsEnabled = bool.Parse(doc.SelectSingleNode("post/iscommentsenabled").InnerText);
  221. }
  222. if (doc.SelectSingleNode("post/raters") != null)
  223. {
  224. post.Raters = int.Parse(doc.SelectSingleNode("post/raters").InnerText, CultureInfo.InvariantCulture);
  225. }
  226. if (doc.SelectSingleNode("post/rating") != null)
  227. {
  228. post.Rating = float.Parse(
  229. doc.SelectSingleNode("post/rating").InnerText, CultureInfo.GetCultureInfo("en-gb"));
  230. }
  231. if (doc.SelectSingleNode("post/slug") != null)
  232. {
  233. post.Slug = doc.SelectSingleNode("post/slug").InnerText;
  234. }
  235. // Tags
  236. foreach (var node in
  237. doc.SelectNodes("post/tags/tag").Cast<XmlNode>().Where(node => !string.IsNullOrEmpty(node.InnerText)))
  238. {
  239. post.Tags.Add(node.InnerText);
  240. }
  241. // comments
  242. foreach (XmlNode node in doc.SelectNodes("post/comments/comment"))
  243. {
  244. var comment = new Comment
  245. {
  246. Id = new Guid(node.Attributes["id"].InnerText),
  247. ParentId =
  248. (node.Attributes["parentid"] != null)
  249. ? new Guid(node.Attributes["parentid"].InnerText)
  250. : Guid.Empty,
  251. Author = node.SelectSingleNode("author").InnerText,
  252. Email = node.SelectSingleNode("email").InnerText,
  253. Parent = post
  254. };
  255. if (node.SelectSingleNode("country") != null)
  256. {
  257. comment.Country = node.SelectSingleNode("country").InnerText;
  258. }
  259. if (node.SelectSingleNode("ip") != null)
  260. {
  261. comment.IP = node.SelectSingleNode("ip").InnerText;
  262. }
  263. if (node.SelectSingleNode("website") != null)
  264. {
  265. Uri website;
  266. if (Uri.TryCreate(node.SelectSingleNode("website").InnerText, UriKind.Absolute, out website))
  267. {
  268. comment.Website = website;
  269. }
  270. }
  271. if (node.SelectSingleNode("moderatedby") != null)
  272. {
  273. comment.ModeratedBy = node.SelectSingleNode("moderatedby").InnerText;
  274. }
  275. comment.IsApproved = node.Attributes["approved"] == null ||
  276. bool.Parse(node.Attributes["approved"].InnerText);
  277. if (node.SelectSingleNode("avatar") != null)
  278. {
  279. comment.Avatar = node.SelectSingleNode("avatar").InnerText;
  280. }
  281. comment.IsSpam = node.Attributes["spam"] == null ? false :
  282. bool.Parse(node.Attributes["spam"].InnerText);
  283. comment.IsDeleted = node.Attributes["deleted"] == null ? false :
  284. bool.Parse(node.Attributes["deleted"].InnerText);
  285. comment.Content = node.SelectSingleNode("content").InnerText;
  286. comment.DateCreated = DateTime.Parse(
  287. node.SelectSingleNode("date").InnerText, CultureInfo.InvariantCulture);
  288. post.AllComments.Add(comment);
  289. }
  290. post.AllComments.Sort();
  291. // categories
  292. foreach (var cat in from XmlNode node in doc.SelectNodes("post/categories/category")
  293. select new Guid(node.InnerText)
  294. into key select Category.GetCategory(key)
  295. into cat where cat != null select cat)
  296. {
  297. // CategoryDictionary.Instance.ContainsKey(key))
  298. post.Categories.Add(cat);
  299. }
  300. // Notification e-mails
  301. foreach (XmlNode node in doc.SelectNodes("post/notifications/email"))
  302. {
  303. post.NotificationEmails.Add(node.InnerText);
  304. }
  305. return post;
  306. }
  307. /// <summary>
  308. /// Updates an existing Post in the data store specified by the provider.
  309. /// </summary>
  310. /// <param name="post">
  311. /// The post to update.
  312. /// </param>
  313. public override void UpdatePost(Post post)
  314. {
  315. this.InsertPost(post);
  316. }
  317. #endregion
  318. }
  319. }