diff --git a/composer.json b/composer.json index 0ddc7e8..10d45b1 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,8 @@ "ezyang/htmlpurifier": "4.*", "indieweb/link-rel-parser": "0.1.*", "dg/twitter-php": "^3.6", - "p3k/timezone": "*" + "p3k/timezone": "*", + "cebe/markdown": "~1.1.1" }, "autoload": { "files": [ @@ -21,6 +22,7 @@ "lib/HTTP.php", "lib/Formats/Mf2.php", "lib/Formats/Instagram.php", + "lib/Formats/GitHub.php", "lib/Formats/Twitter.php", "lib/Formats/XKCD.php", "lib/Formats/HTMLPurifier_AttrDef_HTML_Microformats2.php" diff --git a/composer.lock b/composer.lock index b202ea7..c8bb14c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,68 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "0a5322d457812e527b5bd2b8c34d205d", + "content-hash": "cb96c21fe4605055f01f595720b750df", "packages": [ + { + "name": "cebe/markdown", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/cebe/markdown.git", + "reference": "c30eb5e01fe021cc5bba2f9ee0eeef96d4931166" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cebe/markdown/zipball/c30eb5e01fe021cc5bba2f9ee0eeef96d4931166", + "reference": "c30eb5e01fe021cc5bba2f9ee0eeef96d4931166", + "shasum": "" + }, + "require": { + "lib-pcre": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "cebe/indent": "*", + "facebook/xhprof": "*@dev", + "phpunit/phpunit": "4.1.*" + }, + "bin": [ + "bin/markdown" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "cebe\\markdown\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Carsten Brandt", + "email": "mail@cebe.cc", + "homepage": "http://cebe.cc/", + "role": "Creator" + } + ], + "description": "A super fast, highly extensible markdown parser for PHP", + "homepage": "https://github.com/cebe/markdown#readme", + "keywords": [ + "extensible", + "fast", + "gfm", + "markdown", + "markdown-extra" + ], + "time": "2016-09-14T20:40:20+00:00" + }, { "name": "dg/twitter-php", "version": "v3.6", @@ -404,6 +464,57 @@ ], "time": "2016-03-14T12:13:34+00:00" }, + { + "name": "michelf/php-markdown", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/michelf/php-markdown.git", + "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/1f51cc520948f66cd2af8cbc45a5ee175e774220", + "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-lib": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Michelf": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Michel Fortin", + "email": "michel.fortin@michelf.ca", + "homepage": "https://michelf.ca/", + "role": "Developer" + }, + { + "name": "John Gruber", + "homepage": "https://daringfireball.net/" + } + ], + "description": "PHP Markdown", + "homepage": "https://michelf.ca/projects/php-markdown/", + "keywords": [ + "markdown" + ], + "time": "2016-10-29T18:58:20+00:00" + }, { "name": "nikic/fast-route", "version": "v0.8.0", diff --git a/controllers/Parse.php b/controllers/Parse.php index 93386b5..23321da 100644 --- a/controllers/Parse.php +++ b/controllers/Parse.php @@ -99,6 +99,10 @@ class Parse { return $this->parseTwitterURL($request, $response, $url, $match); } + if($host == 'github.com') { + return $this->parseGitHubURL($request, $response, $url); + } + // Now fetch the URL and check for any curl errors // Don't cache the response if a token is used to fetch it if($this->mc && !$request->get('token')) { @@ -348,7 +352,41 @@ class Parse { 'code' => 0 ]); } + } + + private function parseGitHubURL(&$request, &$response, $url) { + $fields = ['github_access_token']; + $creds = []; + foreach($fields as $f) { + if($v=$request->get($f)) + $creds[$f] = $v; + } + $data = false; + $json = $request->get('json'); + if($json) { + // Accept GitHub JSON and parse that if provided + list($data, $json) = Formats\GitHub::parse($this->http, $url, null, $json); + } else { + // Otherwise fetch the post unauthenticated or with the provided access token + list($data, $json) = Formats\GitHub::parse($this->http, $url, $creds); + } + if($data) { + if($request->get('include_original')) + $data['original'] = $json; + $data['url'] = $url; + $data['code'] = 200; + return $this->respond($response, 200, $data); + } else { + return $this->respond($response, 200, [ + 'data' => [ + 'type' => 'unknown' + ], + 'url' => $url, + 'code' => 0 + ]); + } } + } diff --git a/lib/Formats/GitHub.php b/lib/Formats/GitHub.php new file mode 100644 index 0000000..7f4ec41 --- /dev/null +++ b/lib/Formats/GitHub.php @@ -0,0 +1,119 @@ +get($apiurl); + if($response['code'] != 200) { + return [null, null]; + } + + $data = json_decode($response['body'], true); + } else { + $data = json_decode($json, true); + } + + if(!$data) { + return [null, null]; + } + + // Start building the h-entry + $entry = array( + 'type' => ($type == 'repo' ? 'repo' : 'entry'), + 'url' => $url, + 'author' => [ + 'type' => 'card', + 'name' => null, + 'photo' => null, + 'url' => null + ] + ); + + if($type == 'repo') + $authorkey = 'owner'; + else + $authorkey = 'user'; + + $entry['author']['name'] = $data[$authorkey]['login']; + $entry['author']['photo'] = $data[$authorkey]['avatar_url']; + $entry['author']['url'] = $data[$authorkey]['html_url']; + + if($type == 'pull') { + $entry['name'] = '#' . $pull . ' ' . $data['title']; + } elseif($type == 'issue') { + $entry['name'] = '#' . $issue . ' ' . $data['title']; + } elseif($type == 'repo') { + $entry['name'] = $data['name']; + } + + if($type == 'repo') { + if(!empty($data['description'])) + $entry['summary'] = $data['description']; + } + + if($type != 'repo' && !empty($data['body'])) { + $parser = new GithubMarkdown(); + + $entry['content'] = [ + 'text' => $data['body'], + 'html' => $parser->parse($data['body']) + ]; + } + + if(!empty($data['labels'])) { + $entry['category'] = $data['labels']; + } + + $entry['published'] = $data['created_at']; + + #$entry['author'] + + + $response = [ + 'data' => $entry + ]; + + return [$response, $json]; + } + +} diff --git a/tests/GitHubTest.php b/tests/GitHubTest.php new file mode 100644 index 0000000..99f5334 --- /dev/null +++ b/tests/GitHubTest.php @@ -0,0 +1,96 @@ +client = new Parse(); + $this->client->http = new p3k\HTTPTest(dirname(__FILE__).'/data/'); + $this->client->mc = null; + } + + private function parse($params) { + $request = new Request($params); + $response = new Response(); + return $this->client->parse($request, $response); + } + + public function testGitHubPull() { + // Original URL: https://github.com/idno/Known/pull/1690 + $url = 'https://github.com/idno/Known/pull/1690'; + $response = $this->parse(['url' => $url]); + + $body = $response->getContent(); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode($body, true); + + $this->assertEquals('entry', $data['data']['type']); + $this->assertEquals('2017-04-10T17:44:57Z', $data['data']['published']); + $this->assertEquals('aaronpk', $data['data']['author']['name']); + $this->assertEquals('https://github.com/aaronpk', $data['data']['author']['url']); + $this->assertEquals('https://avatars2.githubusercontent.com/u/113001?v=3', $data['data']['author']['photo']); + $this->assertEquals('#1690 fixes bookmark Microformats markup', $data['data']['name']); + $this->assertContains('
', $data['data']['content']['html']); + $this->assertContains('', $data['data']['content']['html']); + $this->assertContains('> sebsel', $data['data']['content']['text']); + } + + public function testGitHubRepo() { + $url = 'https://github.com/aaronpk/XRay'; + $response = $this->parse(['url' => $url]); + + $body = $response->getContent(); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode($body, true); + + $this->assertEquals('repo', $data['data']['type']); + $this->assertEquals('2016-02-19T16:53:20Z', $data['data']['published']); + $this->assertEquals('aaronpk', $data['data']['author']['name']); + $this->assertEquals('https://github.com/aaronpk', $data['data']['author']['url']); + $this->assertEquals('https://avatars2.githubusercontent.com/u/113001?v=3', $data['data']['author']['photo']); + $this->assertEquals('XRay', $data['data']['name']); + $this->assertEquals('X-Ray returns structured data from any URL', $data['data']['summary']); + } + + public function testGitHubIssueComment() { + $url = 'https://github.com/aaronpk/XRay/issues/25#issuecomment-275433926'; + $response = $this->parse(['url' => $url]); + + $body = $response->getContent(); + $this->assertEquals(200, $response->getStatusCode()); + $data = json_decode($body, true); + + $this->assertEquals('entry', $data['data']['type']); + $this->assertEquals('2017-01-26T16:24:37Z', $data['data']['published']); + $this->assertEquals('sebsel', $data['data']['author']['name']); + $this->assertEquals('https://avatars3.githubusercontent.com/u/16517999?v=3', $data['data']['author']['photo']); + $this->assertEquals('https://github.com/sebsel', $data['data']['author']['url']); + $this->assertContains('Well it\'s just that php-comments does more than XRay does currently. But that\'s no good reason.
', $data['data']['content']['html']); + $this->assertContains('', $data['data']['content']['html']); + $this->assertContains('```php', $data['data']['content']['text']); + $this->assertNotContains('name', $data['data']); + } + + +} diff --git a/tests/data/api.github.com/repos_aaronpk_XRay b/tests/data/api.github.com/repos_aaronpk_XRay new file mode 100644 index 0000000..ba1e499 --- /dev/null +++ b/tests/data/api.github.com/repos_aaronpk_XRay @@ -0,0 +1,116 @@ +HTTP/1.1 200 OK +Server: GitHub.com +Date: Fri, 21 Apr 2017 15:58:55 GMT +Content-Type: application/json; charset=utf-8 +Content-Length: 4836 +Status: 200 OK +X-RateLimit-Limit: 60 +X-RateLimit-Remaining: 50 +X-RateLimit-Reset: 1492790890 +Cache-Control: public, max-age=60, s-maxage=60 +Vary: Accept +ETag: "8ddf616bbf7eed6b81084fcdd8087305" +Last-Modified: Thu, 02 Mar 2017 18:36:20 GMT +X-GitHub-Media-Type: github.v3; format=json +Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval +Access-Control-Allow-Origin: * +Content-Security-Policy: default-src 'none' +Strict-Transport-Security: max-age=31536000; includeSubdomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: deny +X-XSS-Protection: 1; mode=block +Vary: Accept-Encoding +X-Served-By: 10ea50bffaded85949561216def301f3 +X-GitHub-Request-Id: CED9:2FD1:1A1E1CE:209452A:58FA2C3F + +{ + "id": 52102380, + "name": "XRay", + "full_name": "aaronpk/XRay", + "owner": { + "login": "aaronpk", + "id": 113001, + "avatar_url": "https://avatars2.githubusercontent.com/u/113001?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/aaronpk", + "html_url": "https://github.com/aaronpk", + "followers_url": "https://api.github.com/users/aaronpk/followers", + "following_url": "https://api.github.com/users/aaronpk/following{/other_user}", + "gists_url": "https://api.github.com/users/aaronpk/gists{/gist_id}", + "starred_url": "https://api.github.com/users/aaronpk/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/aaronpk/subscriptions", + "organizations_url": "https://api.github.com/users/aaronpk/orgs", + "repos_url": "https://api.github.com/users/aaronpk/repos", + "events_url": "https://api.github.com/users/aaronpk/events{/privacy}", + "received_events_url": "https://api.github.com/users/aaronpk/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/aaronpk/XRay", + "description": "X-Ray returns structured data from any URL", + "fork": false, + "url": "https://api.github.com/repos/aaronpk/XRay", + "forks_url": "https://api.github.com/repos/aaronpk/XRay/forks", + "keys_url": "https://api.github.com/repos/aaronpk/XRay/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/aaronpk/XRay/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/aaronpk/XRay/teams", + "hooks_url": "https://api.github.com/repos/aaronpk/XRay/hooks", + "issue_events_url": "https://api.github.com/repos/aaronpk/XRay/issues/events{/number}", + "events_url": "https://api.github.com/repos/aaronpk/XRay/events", + "assignees_url": "https://api.github.com/repos/aaronpk/XRay/assignees{/user}", + "branches_url": "https://api.github.com/repos/aaronpk/XRay/branches{/branch}", + "tags_url": "https://api.github.com/repos/aaronpk/XRay/tags", + "blobs_url": "https://api.github.com/repos/aaronpk/XRay/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/aaronpk/XRay/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/aaronpk/XRay/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/aaronpk/XRay/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/aaronpk/XRay/statuses/{sha}", + "languages_url": "https://api.github.com/repos/aaronpk/XRay/languages", + "stargazers_url": "https://api.github.com/repos/aaronpk/XRay/stargazers", + "contributors_url": "https://api.github.com/repos/aaronpk/XRay/contributors", + "subscribers_url": "https://api.github.com/repos/aaronpk/XRay/subscribers", + "subscription_url": "https://api.github.com/repos/aaronpk/XRay/subscription", + "commits_url": "https://api.github.com/repos/aaronpk/XRay/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/aaronpk/XRay/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/aaronpk/XRay/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/aaronpk/XRay/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/aaronpk/XRay/contents/{+path}", + "compare_url": "https://api.github.com/repos/aaronpk/XRay/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/aaronpk/XRay/merges", + "archive_url": "https://api.github.com/repos/aaronpk/XRay/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/aaronpk/XRay/downloads", + "issues_url": "https://api.github.com/repos/aaronpk/XRay/issues{/number}", + "pulls_url": "https://api.github.com/repos/aaronpk/XRay/pulls{/number}", + "milestones_url": "https://api.github.com/repos/aaronpk/XRay/milestones{/number}", + "notifications_url": "https://api.github.com/repos/aaronpk/XRay/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/aaronpk/XRay/labels{/name}", + "releases_url": "https://api.github.com/repos/aaronpk/XRay/releases{/id}", + "deployments_url": "https://api.github.com/repos/aaronpk/XRay/deployments", + "created_at": "2016-02-19T16:53:20Z", + "updated_at": "2017-03-02T18:36:20Z", + "pushed_at": "2017-04-19T16:22:04Z", + "git_url": "git://github.com/aaronpk/XRay.git", + "ssh_url": "git@github.com:aaronpk/XRay.git", + "clone_url": "https://github.com/aaronpk/XRay.git", + "svn_url": "https://github.com/aaronpk/XRay", + "homepage": "https://xray.p3k.io", + "size": 2189, + "stargazers_count": 17, + "watchers_count": 17, + "language": "PHP", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "forks_count": 2, + "mirror_url": null, + "open_issues_count": 14, + "forks": 2, + "open_issues": 14, + "watchers": 17, + "default_branch": "master", + "network_count": 2, + "subscribers_count": 10 +} \ No newline at end of file diff --git a/tests/data/api.github.com/repos_aaronpk_XRay_issues_25 b/tests/data/api.github.com/repos_aaronpk_XRay_issues_25 new file mode 100644 index 0000000..525487c --- /dev/null +++ b/tests/data/api.github.com/repos_aaronpk_XRay_issues_25 @@ -0,0 +1,71 @@ +HTTP/1.1 200 OK +Server: GitHub.com +Date: Fri, 21 Apr 2017 15:57:52 GMT +Content-Type: application/json; charset=utf-8 +Content-Length: 2188 +Status: 200 OK +X-RateLimit-Limit: 60 +X-RateLimit-Remaining: 51 +X-RateLimit-Reset: 1492790890 +Cache-Control: public, max-age=60, s-maxage=60 +Vary: Accept +ETag: "9bd5ea8062c126b9d42f9b86b74337e5" +Last-Modified: Tue, 11 Apr 2017 10:12:57 GMT +X-GitHub-Media-Type: github.v3; format=json +Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval +Access-Control-Allow-Origin: * +Content-Security-Policy: default-src 'none' +Strict-Transport-Security: max-age=31536000; includeSubdomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: deny +X-XSS-Protection: 1; mode=block +Vary: Accept-Encoding +X-Served-By: 15bc4ab707db6d6b474783868c7cc828 +X-GitHub-Request-Id: CE5A:2FD1:1A1AFDC:209084E:58FA2C00 + +{ + "url": "https://api.github.com/repos/aaronpk/XRay/issues/25", + "repository_url": "https://api.github.com/repos/aaronpk/XRay", + "labels_url": "https://api.github.com/repos/aaronpk/XRay/issues/25/labels{/name}", + "comments_url": "https://api.github.com/repos/aaronpk/XRay/issues/25/comments", + "events_url": "https://api.github.com/repos/aaronpk/XRay/issues/25/events", + "html_url": "https://github.com/aaronpk/XRay/issues/25", + "id": 203380820, + "number": 25, + "title": "Post type discovery", + "user": { + "login": "sebsel", + "id": 16517999, + "avatar_url": "https://avatars3.githubusercontent.com/u/16517999?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/sebsel", + "html_url": "https://github.com/sebsel", + "followers_url": "https://api.github.com/users/sebsel/followers", + "following_url": "https://api.github.com/users/sebsel/following{/other_user}", + "gists_url": "https://api.github.com/users/sebsel/gists{/gist_id}", + "starred_url": "https://api.github.com/users/sebsel/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/sebsel/subscriptions", + "organizations_url": "https://api.github.com/users/sebsel/orgs", + "repos_url": "https://api.github.com/users/sebsel/repos", + "events_url": "https://api.github.com/users/sebsel/events{/privacy}", + "received_events_url": "https://api.github.com/users/sebsel/received_events", + "type": "User", + "site_admin": false + }, + "labels": [ + + ], + "state": "open", + "locked": false, + "assignee": null, + "assignees": [ + + ], + "milestone": null, + "comments": 3, + "created_at": "2017-01-26T14:13:42Z", + "updated_at": "2017-01-29T17:59:31Z", + "closed_at": null, + "body": "I don't know if this is the right place, but since I was trying to capture some of php-comments shortcomings, here is a shortcoming of XRay I found :)\r\n\r\n> sebsel a thing to note: php-comments gives a 'type' with values like 'reply' and 'like', but XRay just gives 'type=entry' with a 'like-of'. So they do different things.\r\nhttps://chat.indieweb.org/dev/2017-01-02#t1483372296121000\r\n\r\nhttps://www.w3.org/TR/post-type-discovery/", + "closed_by": null +} \ No newline at end of file diff --git a/tests/data/api.github.com/repos_aaronpk_XRay_issues_comments_275433926 b/tests/data/api.github.com/repos_aaronpk_XRay_issues_comments_275433926 new file mode 100644 index 0000000..ffe2d06 --- /dev/null +++ b/tests/data/api.github.com/repos_aaronpk_XRay_issues_comments_275433926 @@ -0,0 +1,53 @@ +HTTP/1.1 200 OK +Server: GitHub.com +Date: Sat, 22 Apr 2017 20:45:04 GMT +Content-Type: application/json; charset=utf-8 +Content-Length: 3408 +Status: 200 OK +X-RateLimit-Limit: 60 +X-RateLimit-Remaining: 58 +X-RateLimit-Reset: 1492894908 +Cache-Control: public, max-age=60, s-maxage=60 +Vary: Accept +ETag: "fc180b8dec148356f2bfb61fd5b1a7c8" +Last-Modified: Tue, 11 Apr 2017 10:12:57 GMT +X-GitHub-Media-Type: github.v3; format=json +Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval +Access-Control-Allow-Origin: * +Content-Security-Policy: default-src 'none' +Strict-Transport-Security: max-age=31536000; includeSubdomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: deny +X-XSS-Protection: 1; mode=block +Vary: Accept-Encoding +X-Served-By: 46808ddc41c302090177e58148908b23 +X-GitHub-Request-Id: CA6A:2FD0:280B9D7:3215E95:58FBC0CF + +{ + "url": "https://api.github.com/repos/aaronpk/XRay/issues/comments/275433926", + "html_url": "https://github.com/aaronpk/XRay/issues/25#issuecomment-275433926", + "issue_url": "https://api.github.com/repos/aaronpk/XRay/issues/25", + "id": 275433926, + "user": { + "login": "sebsel", + "id": 16517999, + "avatar_url": "https://avatars3.githubusercontent.com/u/16517999?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/sebsel", + "html_url": "https://github.com/sebsel", + "followers_url": "https://api.github.com/users/sebsel/followers", + "following_url": "https://api.github.com/users/sebsel/following{/other_user}", + "gists_url": "https://api.github.com/users/sebsel/gists{/gist_id}", + "starred_url": "https://api.github.com/users/sebsel/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/sebsel/subscriptions", + "organizations_url": "https://api.github.com/users/sebsel/orgs", + "repos_url": "https://api.github.com/users/sebsel/repos", + "events_url": "https://api.github.com/users/sebsel/events{/privacy}", + "received_events_url": "https://api.github.com/users/sebsel/received_events", + "type": "User", + "site_admin": false + }, + "created_at": "2017-01-26T16:24:37Z", + "updated_at": "2017-01-29T17:59:31Z", + "body": "Well it's just that php-comments does more than XRay does currently. But that's no good reason.\r\n\r\nThinking about it: yes, I actually use this.\r\nhttps://indieweb.org/facepile#Sebastiaan_Andeweg\r\n\r\nMy webmentions are sorted by the type-field from php-comments. (That's how the plugin originally worked.) I use it to display in the facepile, with proper icon, or as a comment below it.\r\n\r\nOf course I can write my own logic for it, which I did today to sort my own posts in my indexing database. I had enough of writing checks like that all the time, and creating separate bool fields in my database table. (An entry with a name is an article, but a bookmark with a name is no article.)\r\nThe database-example is NOT a use case for XRay though.\r\n\r\nBelow is my current $page->postType() method (in Kirby), including commented-out things that I don't use, but found on the wiki.\r\n\r\n```php\r\n public function postType() {\r\n if($this->has('like_of')) return 'like';\r\n if($this->has('bookmark_of')) return 'bookmark';\r\n //if($this->has('tag_of')) return 'tag';\r\n if($this->has('repost_of')) return 'repost';\r\n if($this->has('read_of')) return 'read'; // << haven't implemented myself, now\r\n if($this->has('watch_of')) return 'watch'; // << posting as text notes, but I have them!\r\n if($this->has('checkin')) return 'checkin';\r\n //if($this->has('invitee')) return 'invitation';\r\n if($this->has('rsvp')) return 'rsvp';\r\n if($this->has('in_reply_to')) return 'reply';\r\n if($this->type() == 'event') return 'event';\r\n if($this->type() == 'review') return 'review';\r\n if($this->has('wrote')) return 'wrote'; // << is one is for myself only :/\r\n if($this->has('video')) return 'video';\r\n if($this->has('photo')) return 'photo';\r\n if($this->has('name')) return 'article';\r\n if($this->has('text')) return 'note'; // << 'text' = 'content'\r\n return 'entry';\r\n }\r\n```\r\n\r\nOh, and I totally agree on keeping 'type' for Mf2 :)" +} \ No newline at end of file diff --git a/tests/data/api.github.com/repos_idno_Known_pulls_1690 b/tests/data/api.github.com/repos_idno_Known_pulls_1690 new file mode 100644 index 0000000..2abcbf6 --- /dev/null +++ b/tests/data/api.github.com/repos_idno_Known_pulls_1690 @@ -0,0 +1,77 @@ +HTTP/1.1 200 OK +Server: GitHub.com +Date: Fri, 21 Apr 2017 15:08:10 GMT +Content-Type: application/json; charset=utf-8 +Content-Length: 2415 +Status: 200 OK +X-RateLimit-Limit: 60 +X-RateLimit-Remaining: 59 +X-RateLimit-Reset: 1492790890 +Cache-Control: public, max-age=60, s-maxage=60 +Vary: Accept +ETag: "8bb1e470c72305c381e9c1cf336f960f" +Last-Modified: Thu, 20 Apr 2017 12:55:34 GMT +X-GitHub-Media-Type: github.v3; format=json +Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval +Access-Control-Allow-Origin: * +Content-Security-Policy: default-src 'none' +Strict-Transport-Security: max-age=31536000; includeSubdomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: deny +X-XSS-Protection: 1; mode=block +Vary: Accept-Encoding +X-Served-By: e14705a23c085afeff5e104b1fc3922a +X-GitHub-Request-Id: F706:2FD1:1984FFC:1FD658F:58FA2059 + +{ + "url": "https://api.github.com/repos/idno/Known/issues/1690", + "repository_url": "https://api.github.com/repos/idno/Known", + "labels_url": "https://api.github.com/repos/idno/Known/issues/1690/labels{/name}", + "comments_url": "https://api.github.com/repos/idno/Known/issues/1690/comments", + "events_url": "https://api.github.com/repos/idno/Known/issues/1690/events", + "html_url": "https://github.com/idno/Known/pull/1690", + "id": 220719149, + "number": 1690, + "title": "fixes bookmark Microformats markup", + "user": { + "login": "aaronpk", + "id": 113001, + "avatar_url": "https://avatars2.githubusercontent.com/u/113001?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/aaronpk", + "html_url": "https://github.com/aaronpk", + "followers_url": "https://api.github.com/users/aaronpk/followers", + "following_url": "https://api.github.com/users/aaronpk/following{/other_user}", + "gists_url": "https://api.github.com/users/aaronpk/gists{/gist_id}", + "starred_url": "https://api.github.com/users/aaronpk/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/aaronpk/subscriptions", + "organizations_url": "https://api.github.com/users/aaronpk/orgs", + "repos_url": "https://api.github.com/users/aaronpk/repos", + "events_url": "https://api.github.com/users/aaronpk/events{/privacy}", + "received_events_url": "https://api.github.com/users/aaronpk/received_events", + "type": "User", + "site_admin": false + }, + "labels": [ + + ], + "state": "open", + "locked": false, + "assignee": null, + "assignees": [ + + ], + "milestone": null, + "comments": 0, + "created_at": "2017-04-10T17:44:57Z", + "updated_at": "2017-04-20T12:55:34Z", + "closed_at": null, + "pull_request": { + "url": "https://api.github.com/repos/idno/Known/pulls/1690", + "html_url": "https://github.com/idno/Known/pull/1690", + "diff_url": "https://github.com/idno/Known/pull/1690.diff", + "patch_url": "https://github.com/idno/Known/pull/1690.patch" + }, + "body": "## Here's what I fixed or added:\r\n\r\nI updated the bookmark template to use `u-bookmark-of` instead of `p-bookmark`. This fixes the parsed version of bookmark posts.\r\n\r\n## Here's why I did it:\r\n\r\nThe bookmark Microformats were setting only the plaintext `bookmark` property which caused bookmarks to not actually reference the URL they are bookmarks of.\r\n", + "closed_by": null +} \ No newline at end of file diff --git a/tests/data/api.github.com/users_aaronpk b/tests/data/api.github.com/users_aaronpk new file mode 100644 index 0000000..ab87f86 --- /dev/null +++ b/tests/data/api.github.com/users_aaronpk @@ -0,0 +1,57 @@ +HTTP/1.1 200 OK +Server: GitHub.com +Date: Fri, 21 Apr 2017 15:41:52 GMT +Content-Type: application/json; charset=utf-8 +Content-Length: 1275 +Status: 200 OK +X-RateLimit-Limit: 60 +X-RateLimit-Remaining: 57 +X-RateLimit-Reset: 1492790890 +Cache-Control: public, max-age=60, s-maxage=60 +Vary: Accept +ETag: "7c20a2777e3c14616a18c07f4b8f8b64" +Last-Modified: Tue, 18 Apr 2017 22:02:28 GMT +X-GitHub-Media-Type: github.v3; format=json +Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval +Access-Control-Allow-Origin: * +Content-Security-Policy: default-src 'none' +Strict-Transport-Security: max-age=31536000; includeSubdomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: deny +X-XSS-Protection: 1; mode=block +Vary: Accept-Encoding +X-Served-By: d0b3c2c33a23690498aa8e70a435a259 +X-GitHub-Request-Id: C713:2FD0:192EF2D:1F4D147:58FA2840 + +{ + "login": "aaronpk", + "id": 113001, + "avatar_url": "https://avatars2.githubusercontent.com/u/113001?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/aaronpk", + "html_url": "https://github.com/aaronpk", + "followers_url": "https://api.github.com/users/aaronpk/followers", + "following_url": "https://api.github.com/users/aaronpk/following{/other_user}", + "gists_url": "https://api.github.com/users/aaronpk/gists{/gist_id}", + "starred_url": "https://api.github.com/users/aaronpk/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/aaronpk/subscriptions", + "organizations_url": "https://api.github.com/users/aaronpk/orgs", + "repos_url": "https://api.github.com/users/aaronpk/repos", + "events_url": "https://api.github.com/users/aaronpk/events{/privacy}", + "received_events_url": "https://api.github.com/users/aaronpk/received_events", + "type": "User", + "site_admin": false, + "name": "Aaron Parecki", + "company": null, + "blog": "https://aaronparecki.com", + "location": "Portland, OR", + "email": "aaron@parecki.com", + "hireable": null, + "bio": null, + "public_repos": 217, + "public_gists": 143, + "followers": 785, + "following": 51, + "created_at": "2009-08-07T18:27:56Z", + "updated_at": "2017-04-18T22:02:28Z" +} \ No newline at end of file diff --git a/tests/data/api.github.com/users_sebsel b/tests/data/api.github.com/users_sebsel new file mode 100644 index 0000000..016ffec --- /dev/null +++ b/tests/data/api.github.com/users_sebsel @@ -0,0 +1,57 @@ +HTTP/1.1 200 OK +Server: GitHub.com +Date: Sat, 22 Apr 2017 20:46:05 GMT +Content-Type: application/json; charset=utf-8 +Content-Length: 1258 +Status: 200 OK +X-RateLimit-Limit: 60 +X-RateLimit-Remaining: 57 +X-RateLimit-Reset: 1492894908 +Cache-Control: public, max-age=60, s-maxage=60 +Vary: Accept +ETag: "525266177afd22f738e334958dedfc8f" +Last-Modified: Tue, 11 Apr 2017 10:12:57 GMT +X-GitHub-Media-Type: github.v3; format=json +Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval +Access-Control-Allow-Origin: * +Content-Security-Policy: default-src 'none' +Strict-Transport-Security: max-age=31536000; includeSubdomains; preload +X-Content-Type-Options: nosniff +X-Frame-Options: deny +X-XSS-Protection: 1; mode=block +Vary: Accept-Encoding +X-Served-By: eef8b8685a106934dcbb4b7c59fba0bf +X-GitHub-Request-Id: CAE2:2FD0:280DE43:3218CDC:58FBC10C + +{ + "login": "sebsel", + "id": 16517999, + "avatar_url": "https://avatars3.githubusercontent.com/u/16517999?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/sebsel", + "html_url": "https://github.com/sebsel", + "followers_url": "https://api.github.com/users/sebsel/followers", + "following_url": "https://api.github.com/users/sebsel/following{/other_user}", + "gists_url": "https://api.github.com/users/sebsel/gists{/gist_id}", + "starred_url": "https://api.github.com/users/sebsel/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/sebsel/subscriptions", + "organizations_url": "https://api.github.com/users/sebsel/orgs", + "repos_url": "https://api.github.com/users/sebsel/repos", + "events_url": "https://api.github.com/users/sebsel/events{/privacy}", + "received_events_url": "https://api.github.com/users/sebsel/received_events", + "type": "User", + "site_admin": false, + "name": "Sebastiaan Andeweg", + "company": null, + "blog": "https://seblog.nl/", + "location": "Nijmegen, The Netherlands", + "email": null, + "hireable": null, + "bio": null, + "public_repos": 16, + "public_gists": 2, + "followers": 5, + "following": 3, + "created_at": "2016-01-02T15:39:15Z", + "updated_at": "2017-04-11T10:12:57Z" +} \ No newline at end of file