diff --git a/composer.json b/composer.json index b6c4dc4..9e52fc9 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ "league/route": "~1.2", "league/plates": "~3.1", "j4mie/idiorm": "1.5.*", - "p3k/caterpillar": "0.1.*" + "p3k/caterpillar": "0.1.*", + "predis/predis": "1.*" }, "require-dev": { "phpunit/phpunit": "*" diff --git a/composer.lock b/composer.lock index e1b6de1..98fabcf 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "f093ab92ae4ced25546dcff30639c5d9", - "content-hash": "61bdf94447ac95a334eb26e591a7b4e3", + "hash": "608bb1b12f4959a9b2dccdd64046ac57", + "content-hash": "eefd85cb3d0c9cf1666ed057a450544d", "packages": [ { "name": "barnabywalters/mf-cleaner", @@ -671,6 +671,56 @@ ], "time": "2015-08-07 21:42:41" }, + { + "name": "predis/predis", + "version": "v1.0.3", + "source": { + "type": "git", + "url": "https://github.com/nrk/predis.git", + "reference": "84060b9034d756b4d79641667d7f9efe1aeb8e04" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nrk/predis/zipball/84060b9034d756b4d79641667d7f9efe1aeb8e04", + "reference": "84060b9034d756b4d79641667d7f9efe1aeb8e04", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "ext-curl": "Allows access to Webdis when paired with phpiredis", + "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol" + }, + "type": "library", + "autoload": { + "psr-4": { + "Predis\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniele Alessandri", + "email": "suppakilla@gmail.com", + "homepage": "http://clorophilla.net" + } + ], + "description": "Flexible and feature-complete PHP client library for Redis", + "homepage": "http://github.com/nrk/predis", + "keywords": [ + "nosql", + "predis", + "redis" + ], + "time": "2015-07-30 18:34:15" + }, { "name": "symfony/http-foundation", "version": "v2.8.0", diff --git a/controllers/API.php b/controllers/API.php index 1b1ae10..633c860 100644 --- a/controllers/API.php +++ b/controllers/API.php @@ -15,6 +15,7 @@ class API { foreach($headers as $k=>$v) { $response->headers->set($k, $v); } + $response->headers->set('Content-Type', 'application/json'); $response->setContent(json_encode($params)); return $response; } diff --git a/controllers/Controller.php b/controllers/Controller.php index bc049fc..f528576 100644 --- a/controllers/Controller.php +++ b/controllers/Controller.php @@ -47,6 +47,22 @@ class Controller { return $response; } + private static function _icon_for_status($status) { + switch($status) { + case 'success': + case 'accepted': + return 'green checkmark'; + case 'not_supported': + return 'yellow x'; + case 'error': + return 'red x'; + case 'pending': + return 'orange wait'; + default: + return ''; + } + } + public function dashboard(Request $request, Response $response) { if(!$this->_is_logged_in($request, $response)) { return $response; @@ -67,23 +83,11 @@ class Controller { foreach($query as $m) { $statuses = ORM::for_table('webmention_status')->where('webmention_id', $m->id)->order_by_desc('created_at')->find_many(); if(count($statuses) == 0) { - $icon = 'wait'; $status = 'pending'; } else { $status = $statuses[0]->status; - switch($status) { - case 'success': - case 'accepted': - $icon = 'checkmark'; - break; - case 'not_supported': - case 'error': - $icon = 'warning'; - break; - default: - $icon = ''; - } } + $icon = self::_icon_for_status($status); $webmentions[] = [ 'webmention' => $m, @@ -98,6 +102,7 @@ class Controller { 'user' => $this->_user(), 'accounts' => $this->_accounts(), 'site' => $site, + 'role' => $role, 'webmentions' => $webmentions ])); return $response; @@ -120,13 +125,22 @@ class Controller { $statuses = ORM::for_table('webmention_status')->where('webmention_id', $webmention->id)->order_by_desc('created_at')->find_many(); + if(count($statuses) == 0) { + $status = 'pending'; + } else { + $status = $statuses[0]->status; + } + $icon = self::_icon_for_status($status); + $response->setContent(view('webmention-details', [ 'title' => 'Webmention Details', 'user' => $this->_user(), 'accounts' => $this->_accounts(), 'site' => $site, 'webmention' => $webmention, - 'statuses' => $statuses + 'statuses' => $statuses, + 'icon' => $icon, + 'status' => $status ])); return $response; } @@ -173,6 +187,42 @@ class Controller { return $response; } + public function discover_endpoint(Request $request, Response $response) { + if(!$this->_is_logged_in($request, $response)) { + return $response; + } + + $targetURL = $request->get('target'); + + // Cache the discovered result + $cacheKey = 'telegraph:discover_endpoint:'.$targetURL; + if($request->get('ignore_cache') == 'true' || (!$status = redis()->get($cacheKey))) { + $client = new IndieWeb\MentionClient(); + $endpoint = $client->discoverWebmentionEndpoint($targetURL); + if($endpoint) { + $status = 'webmention'; + } else { + $endpoint = $client->discoverPingbackEndpoint($targetURL); + if($endpoint) { + $status = 'pingback'; + } else { + $status = 'none'; + } + } + $cached = false; + redis()->setex($cacheKey, 600, $status); + } else { + $cached = true; + } + + $response->headers->set('Content-Type', 'application/json'); + $response->setContent(json_encode([ + 'status' => $status, + 'cached' => $cached + ])); + return $response; + } + private function _user() { return ORM::for_table('users')->where_id_is(session('user_id'))->find_one(); } diff --git a/lib/helpers.php b/lib/helpers.php index 9e8868c..185e49d 100644 --- a/lib/helpers.php +++ b/lib/helpers.php @@ -25,6 +25,13 @@ function q() { return $caterpillar; } +function redis() { + static $client = false; + if(!$client) + $client = new Predis\Client('tcp://127.0.0.1:6379'); + return $client; +} + function random_string($len) { $charset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; $str = ''; diff --git a/public/index.php b/public/index.php index bfe307b..4ea4574 100644 --- a/public/index.php +++ b/public/index.php @@ -13,6 +13,7 @@ $router->addRoute('GET', '/api', 'Controller::api'); $router->addRoute('GET', '/webmention/{code}/details', 'Controller::webmention_details'); $router->addRoute('GET', '/dashboard/send', 'Controller::dashboard_send'); $router->addRoute('POST', '/dashboard/get_outgoing_links.json', 'Controller::get_outgoing_links'); +$router->addRoute('POST', '/dashboard/discover_endpoint.json', 'Controller::discover_endpoint'); $router->addRoute('POST', '/webmention', 'API::webmention'); $router->addRoute('GET', '/webmention/{code}', 'API::webmention_status'); diff --git a/views/dashboard.php b/views/dashboard.php index 4be1b75..c93610a 100644 --- a/views/dashboard.php +++ b/views/dashboard.php @@ -2,13 +2,31 @@
-
-
- - -
- -
+ +
+
+
+ + +
+ +
+
Enter a URL above to preview and send webmentions from all the links found on the page.
+
+
+
+
+
+
+
+
+ +
+
+
@@ -19,8 +37,18 @@ > - - + +
created_at)) ?> + + + + created_at)) ?> + + source=e($mention['webmention']->source) ?>
target=e($mention['webmention']->target) ?> @@ -30,3 +58,38 @@
+ + diff --git a/views/webmention-details.php b/views/webmention-details.php index 7b25c03..7f61556 100644 --- a/views/webmention-details.php +++ b/views/webmention-details.php @@ -5,6 +5,13 @@

Webmention Request

+ + + + diff --git a/views/webmention-send.php b/views/webmention-send.php index a45fa50..9d34e7d 100644 --- a/views/webmention-send.php +++ b/views/webmention-send.php @@ -16,31 +16,92 @@
Status + + +
Date created_at)) ?>