PageRenderTime 43ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/BlogEngine/BlogEngine.NET/App_Code/BlogImporter.cs

#
C# | 429 lines | 229 code | 56 blank | 144 comment | 18 complexity | 3840bc915e110abb55b27b9894f6f299 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. namespace App_Code
  2. {
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Collections.ObjectModel;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Net;
  9. using System.Web.Script.Services;
  10. using System.Web.Services;
  11. using System.Web.Services.Protocols;
  12. using BlogEngine.Core;
  13. /// <summary>
  14. /// Web Service API for Blog Importer
  15. /// </summary>
  16. [WebService(Namespace = "http://dotnetblogengine.net/")]
  17. [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  18. [ScriptService]
  19. public class BlogImporter : WebService
  20. {
  21. #region Constants and Fields
  22. /// <summary>
  23. /// Gets or sets the authentication header.
  24. /// </summary>
  25. /// <value>The authentication header.</value>
  26. public AuthHeader AuthenticationHeader { get; set; }
  27. #endregion
  28. #region Public Methods
  29. /// <summary>
  30. /// Add Comment to specified post
  31. /// </summary>
  32. /// <param name="postId">
  33. /// postId as string
  34. /// </param>
  35. /// <param name="author">
  36. /// commenter username
  37. /// </param>
  38. /// <param name="email">
  39. /// commenter email
  40. /// </param>
  41. /// <param name="website">
  42. /// commenter url
  43. /// </param>
  44. /// <param name="description">
  45. /// actual comment
  46. /// </param>
  47. /// <param name="date">
  48. /// comment datetime
  49. /// </param>
  50. [SoapHeader("AuthenticationHeader")]
  51. [WebMethod]
  52. public void AddComment(
  53. string postId, string author, string email, string website, string description, DateTime date)
  54. {
  55. Security.ImpersonateUser(AuthenticationHeader.Username, AuthenticationHeader.Password);
  56. if (!Security.IsAuthenticated)
  57. {
  58. throw new InvalidOperationException("Wrong credentials");
  59. }
  60. if (!Security.IsAuthorizedTo(Rights.CreateComments))
  61. {
  62. throw new InvalidOperationException("Insufficient rights to create a comment");
  63. }
  64. // Post post = Post.GetPost(new Guid(postID));
  65. var post = Post.Load(new Guid(postId));
  66. if (post == null)
  67. {
  68. return;
  69. }
  70. var comment = new Comment
  71. {
  72. Id = Guid.NewGuid(),
  73. Author = author,
  74. Email = email,
  75. Content = description,
  76. DateCreated = date,
  77. Parent = post,
  78. IsApproved = true
  79. };
  80. Uri url;
  81. if (Uri.TryCreate(website, UriKind.Absolute, out url))
  82. {
  83. comment.Website = url;
  84. }
  85. post.ImportComment(comment);
  86. post.Import();
  87. }
  88. /// <summary>
  89. /// Add new blog post to system
  90. /// </summary>
  91. /// <param name="import">
  92. /// ImportPost object
  93. /// </param>
  94. /// <param name="previousUrl">
  95. /// Old Post Url (for Url re-writing)
  96. /// </param>
  97. /// <param name="removeDuplicate">
  98. /// Search for duplicate post and remove?
  99. /// </param>
  100. /// <returns>
  101. /// string containing unique post identifier
  102. /// </returns>
  103. [SoapHeader("AuthenticationHeader")]
  104. [WebMethod]
  105. public string AddPost(ImportPost import, string previousUrl, bool removeDuplicate)
  106. {
  107. Security.ImpersonateUser(AuthenticationHeader.Username, AuthenticationHeader.Password);
  108. if (!Security.IsAuthenticated)
  109. {
  110. throw new InvalidOperationException("Wrong credentials");
  111. }
  112. if (!Security.IsAuthorizedTo(Rights.CreateNewPosts))
  113. {
  114. throw new InvalidOperationException("Insufficient rights to create a new post");
  115. }
  116. if (removeDuplicate && !Post.IsTitleUnique(import.Title))
  117. {
  118. // Search for matching post (by date and title) and delete it
  119. foreach (var temp in
  120. Post.GetPostsByDate(import.PostDate.AddDays(-2), import.PostDate.AddDays(2)).Where(
  121. temp => temp.Title == import.Title))
  122. {
  123. temp.Delete();
  124. temp.Import();
  125. }
  126. }
  127. var post = new Post
  128. {
  129. Title = import.Title,
  130. Author = import.Author,
  131. DateCreated = import.PostDate,
  132. DateModified = import.PostDate,
  133. Content = import.Content,
  134. Description = import.Description,
  135. IsPublished = import.Publish
  136. };
  137. // TODO: Save Previous Url?
  138. AddCategories(import.Categories, post);
  139. // Tag Support:
  140. // No tags. Use categories.
  141. post.Tags.AddRange(import.Tags.Count == 0 ? import.Categories : import.Tags);
  142. post.Import();
  143. return post.Id.ToString();
  144. }
  145. /// <summary>
  146. /// Relative File Handler path
  147. /// </summary>
  148. /// <returns>
  149. /// file handler path as string
  150. /// </returns>
  151. [WebMethod]
  152. public string BlogFileHandler()
  153. {
  154. return "file.axd?file=";
  155. }
  156. /// <summary>
  157. /// Relative Image Handler path
  158. /// </summary>
  159. /// <returns>
  160. /// image handler path as string
  161. /// </returns>
  162. [WebMethod]
  163. public string BlogImageHandler()
  164. {
  165. return "image.axd?picture=";
  166. }
  167. /// <summary>
  168. /// Name/Type of Blog Software
  169. /// </summary>
  170. /// <returns>
  171. /// Blog Software name
  172. /// </returns>
  173. [WebMethod]
  174. public string BlogType()
  175. {
  176. return "BlogEngine.NET";
  177. }
  178. /// <summary>
  179. /// Version Number of the Blog
  180. /// </summary>
  181. /// <returns>
  182. /// Version number in string
  183. /// </returns>
  184. [WebMethod]
  185. public string BlogVersion()
  186. {
  187. return BlogSettings.Instance.Version();
  188. }
  189. /// <summary>
  190. /// Force Reload of all posts
  191. /// </summary>
  192. [SoapHeader("AuthenticationHeader")]
  193. [WebMethod]
  194. public void ForceReload()
  195. {
  196. Security.ImpersonateUser(AuthenticationHeader.Username, AuthenticationHeader.Password);
  197. if (!Security.IsAuthenticated)
  198. {
  199. throw new InvalidOperationException("Wrong credentials");
  200. }
  201. if (!Security.IsAuthorizedTo(Rights.CreateNewPosts))
  202. {
  203. throw new InvalidOperationException("Insufficient rights to reload posts");
  204. }
  205. Post.Reload();
  206. }
  207. /// <summary>
  208. /// Downloads specified file to specified location
  209. /// </summary>
  210. /// <param name="source">
  211. /// source file path
  212. /// </param>
  213. /// <param name="destination">
  214. /// relative destination path
  215. /// </param>
  216. /// <returns>
  217. /// Wether the file was downloaded
  218. /// </returns>
  219. [SoapHeader("AuthenticationHeader")]
  220. [WebMethod]
  221. public bool GetFile(string source, string destination)
  222. {
  223. bool response;
  224. try
  225. {
  226. Security.ImpersonateUser(AuthenticationHeader.Username, AuthenticationHeader.Password);
  227. if (!Security.IsAuthenticated)
  228. {
  229. throw new InvalidOperationException("Wrong credentials");
  230. }
  231. var rootPath = string.Format("{0}files/", Blog.CurrentInstance.StorageLocation);
  232. var serverPath = Server.MapPath(rootPath);
  233. var saveFolder = serverPath;
  234. var fileName = destination;
  235. // Check/Create Folders & Fix fileName
  236. if (fileName.LastIndexOf('/') <= -1 && saveFolder.EndsWith(Path.DirectorySeparatorChar.ToString()))
  237. {
  238. saveFolder = saveFolder.Substring(0, saveFolder.Length - 1);
  239. }
  240. else
  241. {
  242. saveFolder += fileName.Substring(0, fileName.LastIndexOf('/'));
  243. saveFolder = saveFolder.Replace('/', Path.DirectorySeparatorChar);
  244. fileName = fileName.Substring(fileName.LastIndexOf('/') + 1);
  245. }
  246. if (!Directory.Exists(saveFolder))
  247. {
  248. Directory.CreateDirectory(saveFolder);
  249. }
  250. saveFolder += Path.DirectorySeparatorChar;
  251. using (var client = new WebClient())
  252. {
  253. client.DownloadFile(source, saveFolder + fileName);
  254. }
  255. response = true;
  256. }
  257. catch (Exception ex)
  258. {
  259. // The file probably didn't exist. No action needed.
  260. Utils.Log("BlogImporter.GetFile(): " + ex.Message);
  261. response = false;
  262. }
  263. return response;
  264. }
  265. #endregion
  266. #region Methods
  267. /// <summary>
  268. /// Adds the categories.
  269. /// </summary>
  270. /// <param name="categories">
  271. /// The categories.
  272. /// </param>
  273. /// <param name="post">
  274. /// The post to add to.
  275. /// </param>
  276. private static void AddCategories(IEnumerable<string> categories, IPublishable post)
  277. {
  278. try
  279. {
  280. foreach (var category in categories)
  281. {
  282. var added = false;
  283. var category1 = category;
  284. foreach (var cat in
  285. Category.Categories.Where(
  286. cat => cat.Title.Equals(category1, StringComparison.OrdinalIgnoreCase)))
  287. {
  288. post.Categories.Add(cat);
  289. added = true;
  290. }
  291. if (added)
  292. {
  293. continue;
  294. }
  295. var newCat = new Category(category, string.Empty);
  296. newCat.Save();
  297. post.Categories.Add(newCat);
  298. }
  299. }
  300. catch (Exception ex)
  301. {
  302. Utils.Log("BlogImporter.AddCategories(): " + ex.Message);
  303. }
  304. }
  305. #endregion
  306. /// <summary>
  307. /// The auth header.
  308. /// </summary>
  309. public class AuthHeader : SoapHeader
  310. {
  311. #region Constants and Fields
  312. /// <summary>
  313. /// Gets or sets the password.
  314. /// </summary>
  315. /// <value>The password.</value>
  316. public string Password { get; set; }
  317. /// <summary>
  318. /// Gets or sets the username.
  319. /// </summary>
  320. /// <value>The username.</value>
  321. public string Username { get; set; }
  322. #endregion
  323. }
  324. /// <summary>
  325. /// The import post.
  326. /// </summary>
  327. public class ImportPost
  328. {
  329. #region Constants and Fields
  330. /// <summary>
  331. /// Gets or sets the author.
  332. /// </summary>
  333. /// <value>The author.</value>
  334. public string Author { get; set; }
  335. /// <summary>
  336. /// Gets or sets the categories.
  337. /// </summary>
  338. /// <value>The categories.</value>
  339. public Collection<string> Categories { get; set; }
  340. /// <summary>
  341. /// Gets or sets the content.
  342. /// </summary>
  343. /// <value>The content.</value>
  344. public string Content { get; set; }
  345. /// <summary>
  346. /// Gets or sets the description.
  347. /// </summary>
  348. /// <value>The description.</value>
  349. public string Description { get; set; }
  350. /// <summary>
  351. /// Gets or sets the post date.
  352. /// </summary>
  353. /// <value>The post date.</value>
  354. public DateTime PostDate { get; set; }
  355. /// <summary>
  356. /// Gets or sets a value indicating whether this <see cref="ImportPost"/> is publish.
  357. /// </summary>
  358. /// <value><c>true</c> if publish; otherwise, <c>false</c>.</value>
  359. public bool Publish { get; set; }
  360. /// <summary>
  361. /// Gets or sets the tags.
  362. /// </summary>
  363. /// <value>The tags collection.</value>
  364. public Collection<string> Tags { get; set; }
  365. /// <summary>
  366. /// Gets or sets the title.
  367. /// </summary>
  368. /// <value>The title.</value>
  369. public string Title { get; set; }
  370. #endregion
  371. }
  372. }
  373. }