From b2e311635063e2ffb5bf95985c68fed968dd3ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Guillot?= Date: Wed, 24 Dec 2014 13:50:20 -0500 Subject: [PATCH] Add Instapaper support --- assets/css/app.css | 8 +++ controllers/config.php | 2 +- locales/cs_CZ/translations.php | 5 ++ locales/de_DE/translations.php | 5 ++ locales/es_ES/translations.php | 5 ++ locales/fr_FR/translations.php | 5 ++ locales/it_IT/translations.php | 5 ++ locales/pt_BR/translations.php | 5 ++ locales/zh_CN/translations.php | 5 ++ models/config.php | 7 ++- models/schema.php | 7 +++ models/service.php | 58 +++++++++++++---- templates/services.php | 14 ++++- vendor/autoload.php | 2 +- vendor/composer/autoload_real.php | 10 +-- vendor/composer/installed.json | 8 +-- .../picofeed/lib/PicoFeed/Client/Client.php | 62 +++++++++++++++++++ .../picofeed/lib/PicoFeed/Client/Curl.php | 16 +++++ .../picofeed/lib/PicoFeed/Client/Stream.php | 4 ++ 19 files changed, 207 insertions(+), 26 deletions(-) diff --git a/assets/css/app.css b/assets/css/app.css index d5e873f..21886f9 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -145,6 +145,14 @@ form { border-left: 2px dotted #ddd; } +form h3 { + font-weight: bold; +} + +form h3:first-child { + margin-top: 0; +} + label { cursor: pointer; display: block; diff --git a/controllers/config.php b/controllers/config.php index f31b50b..465a5e1 100644 --- a/controllers/config.php +++ b/controllers/config.php @@ -224,7 +224,7 @@ Router\get_action('services', function() { // Update bookmark services Router\post_action('services', function() { - $values = Request\values() + array('pinboard_enabled' => 0); + $values = Request\values() + array('pinboard_enabled' => 0, 'instapaper_enabled' => 0); Model\Config\check_csrf_values($values); if (Model\Config\save($values)) { diff --git a/locales/cs_CZ/translations.php b/locales/cs_CZ/translations.php index 4ca711f..e281cae 100644 --- a/locales/cs_CZ/translations.php +++ b/locales/cs_CZ/translations.php @@ -222,4 +222,9 @@ return array( // 'Send bookmarks to Pinboard' => '', // 'Pinboard API token' => '', // 'Pinboard tags' => '', + // 'Instapaper username' => '', + // 'Instapaper password' => '', + // 'Instapaper' => '', + // 'Pinboard' => '', + // 'Send bookmarks to Instapaper' => '', ); diff --git a/locales/de_DE/translations.php b/locales/de_DE/translations.php index 52c2047..0632b13 100644 --- a/locales/de_DE/translations.php +++ b/locales/de_DE/translations.php @@ -222,4 +222,9 @@ return array( // 'Send bookmarks to Pinboard' => '', // 'Pinboard API token' => '', // 'Pinboard tags' => '', + // 'Instapaper username' => '', + // 'Instapaper password' => '', + // 'Instapaper' => '', + // 'Pinboard' => '', + // 'Send bookmarks to Instapaper' => '', ); diff --git a/locales/es_ES/translations.php b/locales/es_ES/translations.php index 5bfe129..cc3257a 100644 --- a/locales/es_ES/translations.php +++ b/locales/es_ES/translations.php @@ -222,4 +222,9 @@ return array( // 'Send bookmarks to Pinboard' => '', // 'Pinboard API token' => '', // 'Pinboard tags' => '', + // 'Instapaper username' => '', + // 'Instapaper password' => '', + // 'Instapaper' => '', + // 'Pinboard' => '', + // 'Send bookmarks to Instapaper' => '', ); diff --git a/locales/fr_FR/translations.php b/locales/fr_FR/translations.php index 086eddf..32b26fd 100644 --- a/locales/fr_FR/translations.php +++ b/locales/fr_FR/translations.php @@ -222,4 +222,9 @@ return array( 'Send bookmarks to Pinboard' => 'Envoyer les favoris vers Pinboard', 'Pinboard API token' => 'Jeton d\'accès à l\'API de Pinboard', 'Pinboard tags' => 'Tags Pinboard', + 'Instapaper username' => 'Utilisateur Instapaper', + 'Instapaper password' => 'Mot de passe Instapaper', + 'Instapaper' => 'Instapaper', + 'Pinboard' => 'Pinboard', + 'Send bookmarks to Instapaper' => 'Envoyer les favoris vers Instapaper', ); diff --git a/locales/it_IT/translations.php b/locales/it_IT/translations.php index 2732e2b..503636c 100644 --- a/locales/it_IT/translations.php +++ b/locales/it_IT/translations.php @@ -222,4 +222,9 @@ return array( // 'Send bookmarks to Pinboard' => '', // 'Pinboard API token' => '', // 'Pinboard tags' => '', + // 'Instapaper username' => '', + // 'Instapaper password' => '', + // 'Instapaper' => '', + // 'Pinboard' => '', + // 'Send bookmarks to Instapaper' => '', ); diff --git a/locales/pt_BR/translations.php b/locales/pt_BR/translations.php index a3f893d..3e6cb5e 100644 --- a/locales/pt_BR/translations.php +++ b/locales/pt_BR/translations.php @@ -222,4 +222,9 @@ return array( // 'Send bookmarks to Pinboard' => '', // 'Pinboard API token' => '', // 'Pinboard tags' => '', + // 'Instapaper username' => '', + // 'Instapaper password' => '', + // 'Instapaper' => '', + // 'Pinboard' => '', + // 'Send bookmarks to Instapaper' => '', ); diff --git a/locales/zh_CN/translations.php b/locales/zh_CN/translations.php index a753d48..a0a5eab 100644 --- a/locales/zh_CN/translations.php +++ b/locales/zh_CN/translations.php @@ -222,4 +222,9 @@ return array( // 'Send bookmarks to Pinboard' => '', // 'Pinboard API token' => '', // 'Pinboard tags' => '', + // 'Instapaper username' => '', + // 'Instapaper password' => '', + // 'Instapaper' => '', + // 'Pinboard' => '', + // 'Send bookmarks to Instapaper' => '', ); diff --git a/models/config.php b/models/config.php index 80470b8..b1bf610 100644 --- a/models/config.php +++ b/models/config.php @@ -9,7 +9,7 @@ use PicoDb\Database; use PicoFeed\Config\Config as ReaderConfig; use PicoFeed\Logging\Logger; -const DB_VERSION = 31; +const DB_VERSION = 32; const HTTP_USER_AGENT = 'Miniflux (http://miniflux.net)'; // Get PicoFeed config @@ -303,7 +303,10 @@ function get_all() 'auto_update_url', 'pinboard_enabled', 'pinboard_token', - 'pinboard_tags' + 'pinboard_tags', + 'instapaper_enabled', + 'instapaper_username', + 'instapaper_password' ) ->findOne(); } diff --git a/models/schema.php b/models/schema.php index 07029d2..34bf24e 100644 --- a/models/schema.php +++ b/models/schema.php @@ -5,6 +5,13 @@ namespace Schema; use PDO; use Model\Config; +function version_32($pdo) +{ + $pdo->exec('ALTER TABLE config ADD COLUMN instapaper_enabled INTEGER DEFAULT 0'); + $pdo->exec('ALTER TABLE config ADD COLUMN instapaper_username TEXT'); + $pdo->exec('ALTER TABLE config ADD COLUMN instapaper_password TEXT'); +} + function version_31($pdo) { $pdo->exec('ALTER TABLE config ADD COLUMN pinboard_enabled INTEGER DEFAULT 0'); diff --git a/models/service.php b/models/service.php index 87f3a94..5f6ef3f 100644 --- a/models/service.php +++ b/models/service.php @@ -10,35 +10,69 @@ use PicoFeed\Client\ClientException; // Sync the item to an external service function push($item_id) { + $item = Item\get($item_id); + if ((bool) Config\get('pinboard_enabled')) { - pinboard_add(Item\get($item_id)); + pinboard_add($item); } + + if ((bool) Config\get('instapaper_enabled')) { + instapaper_add($item); + } +} + +// Send item to Instapaper +function instapaper_add(array $item) +{ + $params = array( + 'username' => Config\get('instapaper_username'), + 'password' => Config\get('instapaper_password'), + 'url' => $item['url'], + 'title' => $item['title'], + ); + + $url = 'https://www.instapaper.com/api/add?'.http_build_query($params); + + $client = api_call($url); + + if ($client !== false) { + return $client->getStatusCode() === 201; + } + + return false; } // Add a Pinboard bookmark function pinboard_add(array $item) { - return pinboard_api('/posts/add', array( + $params = array( + 'auth_token' => Config\get('pinboard_token'), + 'format' => 'json', 'url' => $item['url'], 'description' => $item['title'], 'tags' => Config\get('pinboard_tags'), - )); + ); + + $url = 'https://api.pinboard.in/v1/posts/add?'.http_build_query($params); + + $client = api_call($url); + + if ($client !== false) { + $response = json_decode($client->getContent(), true); + return is_array($response) && $response['result_code'] === 'done'; + } + + return false; } -// Pinboard API client -function pinboard_api($method, array $params) +// HTTP client +function api_call($url) { try { - $params += array('auth_token' => Config\get('pinboard_token'), 'format' => 'json'); - $url = 'https://api.pinboard.in/v1'.$method.'?'.http_build_query($params); - $client = Client::getInstance(); $client->setUserAgent(Config\HTTP_USER_AGENT); $client->execute($url); - - $response = json_decode($client->getContent(), true); - - return is_array($response) && $response['result_code'] === 'done'; + return $client; } catch (ClientException $e) { return false; diff --git a/templates/services.php b/templates/services.php index 86b5773..bfe6851 100644 --- a/templates/services.php +++ b/templates/services.php @@ -9,8 +9,10 @@
+
+


@@ -19,7 +21,17 @@
-
+ + + +

+
+ + +
+ + +
diff --git a/vendor/autoload.php b/vendor/autoload.php index 59abddc..313a8b4 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer' . '/autoload_real.php'; -return ComposerAutoloaderInit75276362b3cf9253f7e5cb38a60a4693::getLoader(); +return ComposerAutoloaderInite2d22b082480fbe8c7c1ceae6d7cbe85::getLoader(); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 5527ca4..43e8b5f 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit75276362b3cf9253f7e5cb38a60a4693 +class ComposerAutoloaderInite2d22b082480fbe8c7c1ceae6d7cbe85 { private static $loader; @@ -19,9 +19,9 @@ class ComposerAutoloaderInit75276362b3cf9253f7e5cb38a60a4693 return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit75276362b3cf9253f7e5cb38a60a4693', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInite2d22b082480fbe8c7c1ceae6d7cbe85', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit75276362b3cf9253f7e5cb38a60a4693', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInite2d22b082480fbe8c7c1ceae6d7cbe85', 'loadClassLoader')); $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -42,14 +42,14 @@ class ComposerAutoloaderInit75276362b3cf9253f7e5cb38a60a4693 $includeFiles = require __DIR__ . '/autoload_files.php'; foreach ($includeFiles as $file) { - composerRequire75276362b3cf9253f7e5cb38a60a4693($file); + composerRequiree2d22b082480fbe8c7c1ceae6d7cbe85($file); } return $loader; } } -function composerRequire75276362b3cf9253f7e5cb38a60a4693($file) +function composerRequiree2d22b082480fbe8c7c1ceae6d7cbe85($file) { require $file; } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index f9a20c8..b957988 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -162,18 +162,18 @@ "source": { "type": "git", "url": "https://github.com/fguillot/picoFeed.git", - "reference": "2d538a140020794fad248ccc0f88bb29263a61d6" + "reference": "eefd3f78268627e07ccf31c71cadd4c5ec0955bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fguillot/picoFeed/zipball/2d538a140020794fad248ccc0f88bb29263a61d6", - "reference": "2d538a140020794fad248ccc0f88bb29263a61d6", + "url": "https://api.github.com/repos/fguillot/picoFeed/zipball/eefd3f78268627e07ccf31c71cadd4c5ec0955bd", + "reference": "eefd3f78268627e07ccf31c71cadd4c5ec0955bd", "shasum": "" }, "require": { "php": ">=5.3.0" }, - "time": "2014-12-24 02:16:53", + "time": "2014-12-24 18:41:58", "type": "library", "installation-source": "dist", "autoload": { diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Client.php b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Client.php index 602416e..e91cfd8 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Client.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Client.php @@ -85,6 +85,22 @@ abstract class Client */ protected $proxy_password = ''; + /** + * Basic auth username + * + * @access protected + * @var string + */ + protected $username = ''; + + /** + * Basic auth password + * + * @access protected + * @var string + */ + protected $password = ''; + /** * Client connection timeout * @@ -133,6 +149,14 @@ abstract class Client */ protected $max_body_size = 2097152; // 2MB + /** + * HTTP response status code + * + * @access protected + * @var integer + */ + protected $status_code = 0; + /** * Do the HTTP request * @@ -180,6 +204,7 @@ abstract class Client $response = $this->doRequest(); + $this->status_code = $response['status']; $this->handleNotModifiedResponse($response); $this->handleNotFoundResponse($response); $this->handleNormalResponse($response); @@ -415,6 +440,17 @@ abstract class Client return $this; } + /** + * Get the HTTP response status code + * + * @access public + * @return integer + */ + public function getStatusCode() + { + return $this->status_code; + } + /** * Get the body of the HTTP response * @@ -563,6 +599,32 @@ abstract class Client return $this; } + /** + * Set the username + * + * @access public + * @param string $username Basic Auth username + * @return \PicoFeed\Client\Client + */ + public function setUsername($username) + { + $this->username = $username ?: $this->username; + return $this; + } + + /** + * Set the password + * + * @access public + * @param string $password Basic Auth Password + * @return \PicoFeed\Client\Client + */ + public function setPassword($password) + { + $this->password = $password ?: $this->password; + return $this; + } + /** * Set config object * diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php index 54b3c6e..a284f69 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php @@ -147,6 +147,21 @@ class Curl extends Client return $ch; } + /** + * Prepare curl auth context + * + * @access private + * @return resource $ch + */ + private function prepareAuthContext($ch) + { + if ($this->username && $this->password) { + curl_setopt($ch, CURLOPT_USERPWD, $this->username.':'.$this->password); + } + + return $ch; + } + /** * Prepare curl context * @@ -170,6 +185,7 @@ class Curl extends Client curl_setopt($ch, CURLOPT_COOKIEFILE, 'php://memory'); $ch = $this->prepareProxyContext($ch); + $ch = $this->prepareAuthContext($ch); return $ch; } diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Stream.php b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Stream.php index 32d045c..a74cc39 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Stream.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Stream.php @@ -41,6 +41,10 @@ class Stream extends Client $headers[] = 'Proxy-Authorization: Basic '.base64_encode($this->proxy_username.':'.$this->proxy_password); } + if ($this->username && $this->password) { + $headers[] = 'Authorization: Basic '.base64_encode($this->username.':'.$this->password); + } + return $headers; }