You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
4.2 KiB

5 years ago
5 years ago
  1. <?php
  2. namespace p3k\XRay\Formats;
  3. use DateTime, DateTimeZone;
  4. use Config;
  5. use cebe\markdown\GithubMarkdown;
  6. class GitHub extends Format {
  7. public static function matches_host($url) {
  8. $host = parse_url($url, PHP_URL_HOST);
  9. return $host == 'github.com';
  10. }
  11. public static function matches($url) {
  12. return preg_match('~https://github.com/([^/]+)/([^/]+)/pull/(\d+)$~', $url, $match)
  13. || preg_match('~https://github.com/([^/]+)/([^/]+)/issues/(\d+)$~', $url, $match)
  14. || preg_match('~https://github.com/([^/]+)/([^/]+)$~', $url, $match)
  15. || preg_match('~https://github.com/([^/]+)/([^/]+)/issues/(\d+)#issuecomment-(\d+)~', $url, $match);
  16. }
  17. public static function fetch($http, $url, $creds) {
  18. // Transform the GitHub URL to an API request
  19. if(preg_match('~https://github.com/([^/]+)/([^/]+)/pull/(\d+)$~', $url, $match)) {
  20. $type = 'pull';
  21. $org = $match[1];
  22. $repo = $match[2];
  23. $pull = $match[3];
  24. $apiurl = 'https://api.github.com/repos/'.$org.'/'.$repo.'/pulls/'.$pull;
  25. } elseif(preg_match('~https://github.com/([^/]+)/([^/]+)/issues/(\d+)$~', $url, $match)) {
  26. $type = 'issue';
  27. $org = $match[1];
  28. $repo = $match[2];
  29. $issue = $match[3];
  30. $apiurl = 'https://api.github.com/repos/'.$org.'/'.$repo.'/issues/'.$issue;
  31. } elseif(preg_match('~https://github.com/([^/]+)/([^/]+)$~', $url, $match)) {
  32. $type = 'repo';
  33. $org = $match[1];
  34. $repo = $match[2];
  35. $apiurl = 'https://api.github.com/repos/'.$org.'/'.$repo;
  36. } elseif(preg_match('~https://github.com/([^/]+)/([^/]+)/issues/(\d+)#issuecomment-(\d+)~', $url, $match)) {
  37. $type = 'comment';
  38. $org = $match[1];
  39. $repo = $match[2];
  40. $issue = $match[3];
  41. $comment = $match[4];
  42. $apiurl = 'https://api.github.com/repos/'.$org.'/'.$repo.'/issues/comments/'.$comment;
  43. } else {
  44. return [
  45. 'error' => 'unsupported_url',
  46. 'error_description' => 'This GitHub URL is not supported',
  47. 'error_code' => 400,
  48. ];
  49. }
  50. $headers = [];
  51. if(isset($creds['github_access_token'])) {
  52. $headers[] = 'Authorization: Bearer ' . $creds['github_access_token'];
  53. }
  54. $response = $http->get($apiurl, $headers);
  55. if($response['code'] != 200) {
  56. return [
  57. 'error' => 'github_error',
  58. 'error_description' => $response['body'],
  59. 'code' => $response['code'],
  60. ];
  61. }
  62. return [
  63. 'url' => $url,
  64. 'body' => $response['body'],
  65. 'code' => $response['code'],
  66. ];
  67. }
  68. public static function parse($http, $url, $creds, $json=null) {
  69. if(false) {
  70. } else {
  71. $data = json_decode($json, true);
  72. }
  73. if(!$data) {
  74. return [null, null, 0];
  75. }
  76. // Start building the h-entry
  77. $entry = array(
  78. 'type' => ($type == 'repo' ? 'repo' : 'entry'),
  79. 'url' => $url,
  80. 'author' => [
  81. 'type' => 'card',
  82. 'name' => null,
  83. 'photo' => null,
  84. 'url' => null
  85. ]
  86. );
  87. if($type == 'repo')
  88. $authorkey = 'owner';
  89. else
  90. $authorkey = 'user';
  91. $entry['author']['name'] = $data[$authorkey]['login'];
  92. $entry['author']['photo'] = $data[$authorkey]['avatar_url'];
  93. $entry['author']['url'] = $data[$authorkey]['html_url'];
  94. if($type == 'pull') {
  95. $entry['name'] = '#' . $pull . ' ' . $data['title'];
  96. } elseif($type == 'issue') {
  97. $entry['name'] = '#' . $issue . ' ' . $data['title'];
  98. } elseif($type == 'repo') {
  99. $entry['name'] = $data['name'];
  100. }
  101. if($type == 'repo') {
  102. if(!empty($data['description']))
  103. $entry['summary'] = $data['description'];
  104. }
  105. if($type != 'repo' && !empty($data['body'])) {
  106. $parser = new GithubMarkdown();
  107. $entry['content'] = [
  108. 'text' => $data['body'],
  109. 'html' => $parser->parse($data['body'])
  110. ];
  111. }
  112. if($type == 'comment') {
  113. $entry['in-reply-to'] = ['https://github.com/'.$org.'/'.$repo.'/issues/'.$issue];
  114. }
  115. if(!empty($data['labels'])) {
  116. $entry['category'] = array_map(function($l){
  117. return $l['name'];
  118. }, $data['labels']);
  119. }
  120. $entry['published'] = $data['created_at'];
  121. $r = [
  122. 'data' => $entry
  123. ];
  124. return [$r, $json, $response['code']];
  125. }
  126. }