PageRenderTime 61ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/src/MarkPad/DocumentSources/WebSources/WebDocumentService.cs

https://github.com/bcott/DownmarkerWPF
C# | 213 lines | 190 code | 23 blank | 0 comment | 18 complexity | d35b98f2b3ad8e8467a04a6420ad6c32 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Net;
  6. using System.Security.Cryptography;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using CookComputing.XmlRpc;
  10. using MarkPad.Document;
  11. using MarkPad.DocumentSources.GitHub;
  12. using MarkPad.DocumentSources.MetaWeblog.Service;
  13. using MarkPad.Infrastructure.DialogService;
  14. using MarkPad.Plugins;
  15. using MarkPad.Settings.Models;
  16. namespace MarkPad.DocumentSources.WebSources
  17. {
  18. public class WebDocumentService : IWebDocumentService
  19. {
  20. readonly Func<string, IMetaWeblogService> getMetaWeblog;
  21. readonly IGithubApi githubApi;
  22. readonly IDialogService dialogService;
  23. public WebDocumentService(
  24. IGithubApi githubApi,
  25. Func<string, IMetaWeblogService> getMetaWeblog,
  26. IDialogService dialogService)
  27. {
  28. this.githubApi = githubApi;
  29. this.getMetaWeblog = getMetaWeblog;
  30. this.dialogService = dialogService;
  31. }
  32. public async Task DeleteDocument(BlogSetting blog, Post post)
  33. {
  34. if (blog.WebSourceType == WebSourceType.MetaWebLog)
  35. {
  36. await getMetaWeblog(blog.WebAPI).DeletePostAsync((string)post.postid, blog);
  37. return;
  38. }
  39. if (blog.WebSourceType == WebSourceType.GitHub)
  40. {
  41. return;
  42. }
  43. throw new ArgumentException(string.Format("Unsupported WebSourceType ({0})", blog.WebSourceType));
  44. }
  45. public Task<SaveResult> SaveDocument(BlogSetting blog, WebDocument document)
  46. {
  47. if (blog.WebSourceType == WebSourceType.MetaWebLog)
  48. {
  49. return TaskEx.Run(() =>
  50. {
  51. var categories = document.Categories.ToArray();
  52. return CreateOrUpdateMetaWebLogPost(document, categories, blog);
  53. });
  54. }
  55. if (blog.WebSourceType == WebSourceType.GitHub)
  56. {
  57. return CreateOrUpdateGithubPost(document.Title, document.MarkdownContent, document.AssociatedFiles, blog);
  58. }
  59. return TaskEx.Run(new Func<SaveResult>(() =>
  60. {
  61. throw BadWebSourceTypeException(blog);
  62. }));
  63. }
  64. static ArgumentException BadWebSourceTypeException(BlogSetting blog)
  65. {
  66. return new ArgumentException(string.Format("WebSource Type is invalid ({0})", blog.WebSourceType));
  67. }
  68. public async Task<string> GetDocumentContent(BlogSetting blog, string id)
  69. {
  70. if (blog.WebSourceType == WebSourceType.MetaWebLog)
  71. {
  72. var post = await getMetaWeblog(blog.WebAPI).GetPostAsync(id, blog);
  73. return post.description;
  74. }
  75. if (blog.WebSourceType == WebSourceType.GitHub)
  76. {
  77. return await githubApi.FetchFileContents(blog.Token, blog.Username, blog.WebAPI, id);
  78. }
  79. throw BadWebSourceTypeException(blog);
  80. }
  81. async Task<SaveResult> CreateOrUpdateGithubPost(string postTitle, string content, IEnumerable<FileReference> referencedFiles, BlogSetting blog)
  82. {
  83. var treeToUpload = new GitTree();
  84. var imagesToUpload = referencedFiles.Where(f=>!f.Saved).ToList();
  85. if (imagesToUpload.Count > 0)
  86. {
  87. foreach (var imageToUpload in imagesToUpload)
  88. {
  89. var imageContent = Convert.ToBase64String(File.ReadAllBytes(imageToUpload.FullPath));
  90. var item = new GitFile
  91. {
  92. type = "tree",
  93. path = imageToUpload.FullPath,
  94. mode = ((int)GitTreeMode.SubDirectory),
  95. content = imageContent
  96. };
  97. treeToUpload.tree.Add(item);
  98. }
  99. }
  100. var gitFile = new GitFile
  101. {
  102. path = postTitle,
  103. content = content,
  104. mode = (int)GitTreeMode.File,
  105. type = "blob"
  106. };
  107. treeToUpload.tree.Add(gitFile);
  108. var newTree = await githubApi.NewTree(blog.Token, blog.Username, blog.WebAPI, blog.BlogInfo.blogid, treeToUpload);
  109. var uploadedFile = newTree.Item1.tree.Single(t => t.path == gitFile.path);
  110. foreach (var fileReference in imagesToUpload)
  111. {
  112. fileReference.Saved = true;
  113. }
  114. return new SaveResult
  115. {
  116. Id = uploadedFile.sha,
  117. NewDocumentContent = content
  118. };
  119. }
  120. SaveResult CreateOrUpdateMetaWebLogPost(WebDocument document, string[] categories, BlogSetting blog)
  121. {
  122. var newContent = document.MarkdownContent;
  123. var proxy = getMetaWeblog(blog.WebAPI);
  124. if (document.AssociatedFiles.Count(f=>!f.Saved) > 0)
  125. {
  126. foreach (var imageToUpload in document.AssociatedFiles.Where(f=>!f.Saved))
  127. {
  128. var response = proxy.NewMediaObject(blog, new MediaObject
  129. {
  130. name = imageToUpload.FullPath,
  131. type = "image/png",
  132. bits = File.ReadAllBytes(imageToUpload.FullPath)
  133. });
  134. newContent = newContent.Replace(imageToUpload.RelativePath, response.url);
  135. imageToUpload.Saved = true;
  136. }
  137. }
  138. var newpost = new Post();
  139. try
  140. {
  141. if (string.IsNullOrWhiteSpace(document.Id))
  142. {
  143. var permalink = document.Title;
  144. newpost = new Post
  145. {
  146. permalink = permalink,
  147. title = document.Title,
  148. dateCreated = DateTime.Now,
  149. description = blog.Language == "HTML" ? DocumentParser.GetBodyContents(newContent) : newContent,
  150. categories = categories,
  151. format = blog.Language
  152. };
  153. newpost.postid = proxy.NewPost(blog, newpost, true);
  154. }
  155. else
  156. {
  157. newpost = proxy.GetPost(document.Id, blog);
  158. newpost.title = document.Title;
  159. newpost.description = blog.Language == "HTML" ? DocumentParser.GetBodyContents(newContent) : newContent;
  160. newpost.categories = categories;
  161. newpost.format = blog.Language;
  162. proxy.EditPost(document.Id, blog, newpost, true);
  163. }
  164. }
  165. catch (WebException ex)
  166. {
  167. dialogService.ShowError("Error Publishing", ex.Message, "");
  168. }
  169. catch (XmlRpcException ex)
  170. {
  171. dialogService.ShowError("Error Publishing", ex.Message, "");
  172. }
  173. catch (XmlRpcFaultException ex)
  174. {
  175. dialogService.ShowError("Error Publishing", ex.Message, "");
  176. }
  177. return new SaveResult
  178. {
  179. Id = newpost.postid.ToString(),
  180. NewDocumentContent = newContent
  181. };
  182. }
  183. public static string GetSha1(string value)
  184. {
  185. var data = Encoding.ASCII.GetBytes(value);
  186. var hashData = new SHA1Managed().ComputeHash(data);
  187. return hashData.Aggregate(string.Empty, (current, b) => current + b.ToString("X2"));
  188. }
  189. }
  190. }