PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/src/MarkPad/DocumentSources/GitHub/GithubApi.cs

https://github.com/bcott/DownmarkerWPF
C# | 196 lines | 160 code | 35 blank | 1 comment | 5 complexity | 35aad66b7c19e77ae9d69bfccfe55cad MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Http;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Web;
  9. using MarkPad.DocumentSources.MetaWeblog.Service;
  10. using MarkPad.Settings.Models;
  11. namespace MarkPad.DocumentSources.GitHub
  12. {
  13. public class GithubApi : IGithubApi
  14. {
  15. public const string ClientId = "ed0cdbf084078f60b8a3";
  16. private const string ClientSecret = "a0a442815b7530386c90088a98cfd018877624d2";
  17. public const string RedirectUri = "http://vikingco.de";
  18. private const string Accesstokenuri = "https://github.com/login/oauth/access_token";
  19. private const string ApiBaseUrl = "https://api.github.com/";
  20. public async Task<string> GetToken(string code)
  21. {
  22. var c = new HttpClient();
  23. var data = new Dictionary<string, string>
  24. {
  25. {"client_id", ClientId},
  26. {"client_secret", ClientSecret},
  27. {"code", code}
  28. };
  29. var content = new FormUrlEncodedContent(data);
  30. var request = await c.PostAsync(Accesstokenuri, content);
  31. var result = await request.Content.ReadAsStringAsync();
  32. return GetAccessCode(result);
  33. }
  34. static string GetAccessCode(string result)
  35. {
  36. return HttpUtility.ParseQueryString(result)["access_token"];
  37. }
  38. public async Task<BlogInfo[]> FetchBranches(string token, string user, string repositoryName)
  39. {
  40. var httpClient = new HttpClient();
  41. var url = string.Format("/repos/{0}/{1}/branches", user, repositoryName);
  42. var respose = await httpClient.GetAsync(GetUrl(url, token));
  43. if (respose.StatusCode != HttpStatusCode.OK)
  44. throw new Exception(string.Format("Unable to fetch branches: {0}", respose.ReasonPhrase));
  45. var result = await respose.Content.ReadAsAsync<List<GitBranch>>();
  46. return result.Select(r => new BlogInfo { blogid = r.name, blogName = r.name }).ToArray();
  47. }
  48. public async Task<Post[]> FetchFiles(string user, string repositoryName, string branch, string token)
  49. {
  50. var httpClient = new HttpClient();
  51. var url = string.Format("/repos/{0}/{1}/branches/{2}", user, repositoryName, branch);
  52. var respose = await httpClient.GetAsync(GetUrl(url, token));
  53. var result = await respose.Content.ReadAsAsync<dynamic>();
  54. var treeUrl = TreeUrl(result);
  55. respose = await httpClient.GetAsync(new Uri(treeUrl, UriKind.Absolute));
  56. var tree = await respose.Content.ReadAsAsync<GitTree>();
  57. return ToPosts(tree);
  58. }
  59. static Post[] ToPosts(GitTree tree)
  60. {
  61. return tree
  62. .tree
  63. .Where(i => i.type == "blob")
  64. .Select(i => new Post
  65. {
  66. postid = i.sha,
  67. title = i.path,
  68. permalink = i.url
  69. })
  70. .ToArray();
  71. }
  72. static string TreeUrl(dynamic deserializeObject)
  73. {
  74. var commit = deserializeObject.commit;
  75. var tree = commit.commit.tree;
  76. var treeUrl = (string)tree.url;
  77. return treeUrl;
  78. }
  79. public async Task<string> FetchFileContents(string token, string username, string repository, string sha)
  80. {
  81. var client = new HttpClient();
  82. var url = string.Format("/repos/{0}/{1}/git/blobs/{2}", username, repository, sha);
  83. var restResponse = await client.GetAsync(GetUrl(url, token));
  84. return await GetContent(restResponse);
  85. }
  86. public async Task<Tuple<GitTree, GitCommit>> NewTree(string token, string username, string repository, string branch, GitTree tree)
  87. {
  88. var client = new HttpClient();
  89. //Get base commit ref
  90. var shaLatestCommit = await GetLatestCommitSha(token, username, repository, branch, client);
  91. tree.base_tree = await GetBaseTreeSha(token, username, repository, shaLatestCommit, client);
  92. var gitTree = await GetGitTree(token, username, repository, tree, client);
  93. var gitCommit = await CreateGitCommit(token, username, repository, shaLatestCommit, gitTree, client);
  94. LogResult(await FinaliseCommit(token, username, repository, branch, gitCommit.sha, client));
  95. return Tuple.Create(gitTree, gitCommit);
  96. }
  97. void LogResult(HttpResponseMessage httpResponseMessage)
  98. {
  99. }
  100. async Task<HttpResponseMessage> FinaliseCommit(string token, string username, string repository, string branch, string shaNewCommit,
  101. HttpClient client)
  102. {
  103. var url = string.Format("/repos/{0}/{1}/git/refs/heads/{2}", username, repository, branch);
  104. return await client.PutAsJsonAsync(GetUrl(url, token), new { sha = shaNewCommit});
  105. }
  106. static async Task<GitCommit> CreateGitCommit(string token, string username, string repository, string shaLatestCommit, GitTree gitTree,
  107. HttpClient client)
  108. {
  109. var gitCommit = new GitCommit
  110. {
  111. message = "Update from Markpad",
  112. parents = new[] {shaLatestCommit},
  113. tree = gitTree.sha
  114. };
  115. var url = string.Format("/repos/{0}/{1}/git/commits", username, repository);
  116. var respose = await client.PostAsJsonAsync(GetUrl(url, token), gitCommit);
  117. var content = await respose.Content.ReadAsAsync<dynamic>();
  118. gitCommit.sha = content.sha;
  119. return gitCommit;
  120. }
  121. async Task<GitTree> GetGitTree(string token, string username, string repository, GitTree tree, HttpClient client)
  122. {
  123. var url = string.Format("/repos/{0}/{1}/git/trees", username, repository);
  124. var respose = await client.PostAsJsonAsync(GetUrl(url, token), tree);
  125. return await respose.Content.ReadAsAsync<GitTree>();
  126. }
  127. static async Task<string> GetBaseTreeSha(string token, string username, string repository, string shaLatestCommit, HttpClient client)
  128. {
  129. var url = string.Format("/repos/{0}/{1}/git/commits/{2}", username, repository, shaLatestCommit);
  130. var result = await client.GetAsync(GetUrl(url, token));
  131. var baseTreeResult = await result.Content.ReadAsAsync<dynamic>();
  132. return baseTreeResult.tree.sha;
  133. }
  134. static async Task<string> GetLatestCommitSha(string token, string username, string repository, string branch, HttpClient client)
  135. {
  136. var url = string.Format("/repos/{0}/{1}/git/refs/heads/{2}", username, repository, branch);
  137. var response = await client.GetAsync(GetUrl(url, token));
  138. var refResult = await response.Content.ReadAsAsync<dynamic>();
  139. return refResult.@object.sha;
  140. }
  141. static async Task<string> GetContent(HttpResponseMessage result)
  142. {
  143. var deserializeObject = await result.Content.ReadAsAsync<dynamic>();
  144. if (deserializeObject.encoding == "utf-8")
  145. return deserializeObject.content;
  146. var content = deserializeObject.content;
  147. string encodedData = content;
  148. return DecodeFrom64(encodedData);
  149. }
  150. public static string DecodeFrom64(string encodedData)
  151. {
  152. var encodedDataAsBytes = Convert.FromBase64String(encodedData);
  153. var returnValue = Encoding.UTF8.GetString(encodedDataAsBytes);
  154. return returnValue;
  155. }
  156. private static string GetUrl(string path, string accessToken)
  157. {
  158. return string.Format("{0}/{1}?access_token={2}", ApiBaseUrl.TrimEnd('/'), path.TrimStart('/'), accessToken);
  159. }
  160. }
  161. }