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.

94 lines
2.2 KiB

  1. <?php
  2. namespace p3k\XRay\Formats;
  3. use DateTime, DateTimeZone;
  4. use Config;
  5. use cebe\markdown\GithubMarkdown;
  6. class Hackernews extends Format {
  7. public static function matches_host($url) {
  8. $host = parse_url($url, PHP_URL_HOST);
  9. return $host == 'news.ycombinator.com';
  10. }
  11. public static function matches($url) {
  12. if(preg_match('~https?://news\.ycombinator\.com/item\?id=(\d+)$~', $url, $match))
  13. return $match;
  14. else
  15. return false;
  16. }
  17. public static function fetch($http, $url, $opts) {
  18. $match = self::matches($url);
  19. $response = $http->get('https://hacker-news.firebaseio.com/v0/item/'.$match[1].'.json');
  20. if($response['code'] != 200) {
  21. return [
  22. 'error' => 'hackernews_error',
  23. 'error_description' => $response['body'],
  24. 'code' => $response['code'],
  25. ];
  26. }
  27. return [
  28. 'url' => $url,
  29. 'body' => $response['body'],
  30. 'code' => $response['code'],
  31. ];
  32. }
  33. public static function parse($http_response) {
  34. $json = $http_response['body'];
  35. $url = $http_response['url'];
  36. $data = @json_decode($json, true);
  37. if(!$data)
  38. return self::_unknown();
  39. $match = self::matches($url);
  40. $date = DateTime::createFromFormat('U', $data['time']);
  41. // Start building the h-entry
  42. $entry = array(
  43. 'type' => 'entry',
  44. 'url' => $url,
  45. 'author' => [
  46. 'type' => 'card',
  47. 'name' => $data['by'],
  48. 'photo' => null,
  49. 'url' => 'https://news.ycombinator.com/user?id='.$data['by']
  50. ],
  51. 'published' => $date->format('c')
  52. );
  53. if(isset($data['title'])) {
  54. $entry['name'] = $data['title'];
  55. }
  56. if(isset($data['text'])) {
  57. $htmlContent = trim(self::sanitizeHTML($data['text']));
  58. $textContent = str_replace('<p>', "\n<p>", $htmlContent);
  59. $textContent = strip_tags($textContent);
  60. $entry['content'] = [
  61. 'html' => $htmlContent,
  62. 'text' => $textContent
  63. ];
  64. }
  65. if(isset($data['parent'])) {
  66. $entry['in-reply-to'] = ['https://news.ycombinator.com/item?id='.$data['parent']];
  67. }
  68. $entry['post-type'] = \p3k\XRay\PostType::discover($entry);
  69. return [
  70. 'data' => $entry,
  71. 'original' => $json,
  72. 'source-format' => 'hackernews',
  73. ];
  74. }
  75. }