├── .gitignore ├── README.md ├── auth.php ├── init.php ├── pocket.js ├── pocket.png └── pocketgrey.png /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | oneclickpocket 2 | ============== 3 | 4 | Plugin for Tiny Tiny RSS. Add articles to Pocket with a single click or press of a button. Tested with TT-RSS 1.7.9 and TT-RSS 1.8. 5 | 6 | 7 | Requirements 8 | ------------ 9 | Requirements that exceed TT RSS' requirements: PHP CURL extension has to be enabled 10 | 11 | Installation 12 | ------------ 13 | * Copy the *oneclickpocket* folder to your tt-rss *plugins/* folder. 14 | * Go to your tt-rss Preference page 15 | * Under *Plugins* section enable oneclickpocket plugin 16 | * A new pref pane will show up, named *Pocket* where you have to enter Pocket credentials (this is *not* your Pocket username and password!): 17 | + *Pocket Consumer Key* -- to generate a Consumer Key, head to http://getpocket.com/developer/apps/new -- you only need the permission to Add 18 | + *Pocket Access Token* -- to generate an Access Token, click "Generate Access Token" or open [plugins]/oneclickpocket/auth.php. 19 | 20 | Version history 21 | --------------- 22 | * 0.1 Initial Version 23 | * 0.2 Icon changes colour when clicked 24 | * 0.3 Added a hotkey (thanks to Bas1c), since 0.31 change icon colour for hotkey, too. 25 | * 0.32 Check for CURL and throw error if missing. 26 | * 0.33 Updated for PDO 27 | * 0.34 Update .js for TT-RSS 18.12+ 28 | * 0.35 Update .js for TT-RSS 21.03+ 29 | 30 | Credits 31 | ------- 32 | I used Acaranta's (https://github.com/acaranta) Yourls-plugin as template. 33 | -------------------------------------------------------------------------------- /auth.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Authenticate Pocket 5 | 6 | 7 | 8 | 9 | $consumer_key, 43 | 'code' => $_GET["token"] 44 | ) 45 | ); 46 | 47 | $access_token = explode('&', $oAuthRequest); 48 | $access_token = $access_token[0]; 49 | $access_token = explode('=', $access_token); 50 | $access_token = $access_token[1]; 51 | 52 | } else { 53 | // (2) Obtain request token 54 | $oAuthRequestToken = explode('=', cURL( 55 | 'https://getpocket.com/v3/oauth/request', 56 | array( 57 | 'consumer_key' => $consumer_key, 58 | 'redirect_uri' => $self."?consumer_key=$consumer_key" 59 | ) 60 | )); 61 | 62 | // (3) Redirect user to Pocket to continue authorization 63 | echo ''; 64 | } 65 | 66 | echo '

Authenticate Pocket

'; 67 | echo '
'; 68 | echo ''; 69 | echo ''; 70 | 71 | if (isset($access_token)){ 72 | echo ''; 73 | echo ''; 74 | } 75 | echo '
'; 76 | 77 | } else { 78 | echo '

Authenticate pocket

'; 79 | echo '
'; 80 | echo ''; 81 | echo ''; 82 | echo '
'; 83 | } 84 | ?> 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /init.php: -------------------------------------------------------------------------------- 1 | link = $host->get_link(); 7 | $this->host = $host; 8 | 9 | $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); 10 | $host->add_hook($host::HOOK_PREFS_TAB, $this); 11 | 12 | $host->add_hook($host::HOOK_HOTKEY_MAP, $this); 13 | $host->add_hook($host::HOOK_HOTKEY_INFO, $this); 14 | 15 | } 16 | 17 | function about() { 18 | return array(0.35, 19 | "Add articles to Pocket with a single click", 20 | "fxneumann"); 21 | } 22 | function save() { 23 | 24 | $pocket_consumer_key = clean($_POST["pocket_consumer_key"]); 25 | $this->host->set($this, "pocket_consumer_key", $pocket_consumer_key); 26 | 27 | $pocket_access_token = clean($_POST["pocket_access_token"]); 28 | $this->host->set($this, "pocket_access_token", $pocket_access_token); 29 | 30 | echo "Consumer Key set to
$pocket_consumer_key
Access Token set to
$pocket_access_token"; 31 | } 32 | 33 | function api_version() { 34 | return 2; 35 | } 36 | 37 | function get_js() { 38 | return file_get_contents(dirname(__FILE__) . "/pocket.js"); 39 | } 40 | 41 | function hook_article_button($line) { 42 | $article_id = $line["id"]; 43 | 44 | $rv = ""; 48 | 49 | return $rv; 50 | } 51 | 52 | function getInfo() { 53 | 54 | //retrieve Data from the DB 55 | $id = $_REQUEST['id']; 56 | 57 | $sth = $this->pdo->prepare("SELECT title, link 58 | FROM ttrss_entries, ttrss_user_entries 59 | WHERE id = ? AND ref_id = id AND owner_uid = ?"); 60 | $sth->execute([$id, $_SESSION['uid']]); 61 | 62 | if($sth->rowCount() != 0) { 63 | 64 | $row = $sth->fetch(); 65 | 66 | $title = truncate_string(strip_tags($row['title']), 100, '...'); 67 | $article_link = $row['link']; 68 | } 69 | 70 | $consumer_key = $this->host->get($this, "pocket_consumer_key"); 71 | $pocket_access_token = $this->host->get($this, "pocket_access_token"); 72 | 73 | 74 | //Call Pocket API 75 | 76 | if (function_exists('curl_init')) { 77 | $postfields = array( 78 | 'consumer_key' => $consumer_key, 79 | 'access_token' => $pocket_access_token, 80 | 'url' => $article_link, 81 | 'title' => $title 82 | ); 83 | $cURL = curl_init(); 84 | curl_setopt($cURL, CURLOPT_URL, 'https://getpocket.com/v3/add'); 85 | curl_setopt($cURL, CURLOPT_HEADER, 1); 86 | curl_setopt($cURL, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded;charset=UTF-8')); 87 | curl_setopt($cURL, CURLOPT_RETURNTRANSFER, true); 88 | curl_setopt($cURL, CURLOPT_TIMEOUT, 5); 89 | curl_setopt($cURL, CURLOPT_POST, 4); 90 | curl_setopt($cURL, CURLOPT_POSTFIELDS, http_build_query($postfields)); 91 | $apicall = curl_exec($cURL); 92 | curl_close($cURL); 93 | 94 | //Store error code in $status 95 | $status = preg_match('/^X-Error: .*$/m', $apicall, $matches) ? $matches[0] : 1; 96 | } else { 97 | $status = 'For the plugin to work you need to enable PHP extension CURL!'; 98 | } 99 | //Return information on article and status 100 | print json_encode(array( 101 | "title" => $title, 102 | "link" => $article_link, 103 | "id" => $id, 104 | "status" => $status 105 | )); 106 | } 107 | 108 | function hook_prefs_tab($args) { 109 | //Add preferences pane 110 | if ($args != "prefPrefs") return; 111 | 112 | print "
"; 113 | 114 | print "
"; 115 | 116 | $pocket_consumer_key = $this->host->get($this, "pocket_consumer_key"); 117 | $pocket_access_token = $this->host->get($this, "pocket_access_token"); 118 | 119 | print "
"; 120 | 121 | print ""; 130 | 131 | print ""; 132 | print ""; 133 | print ""; 134 | print ""; 135 | 136 | if (!function_exists('curl_init')) { 137 | print ''; 138 | } 139 | 140 | print ""; 141 | print ''; 142 | print ""; 143 | print ""; 144 | print ""; 145 | print ""; 146 | print "
For the plugin to work you need to enable PHP extension CURL!
".__("Pocket Consumer Key")."Get a Pocket Consumer Key
".__("Pocket Access Token")."Generate Access Token
"; 147 | print "

"; 148 | 149 | print "

"; 150 | 151 | print "
"; #pane 152 | 153 | } 154 | 155 | function hook_hotkey_map($hotkeys) { 156 | // Use the new target "pock_it" to define your own 157 | // hotkey to this function in other plugins. 158 | $hotkeys['i'] = 'pock_it'; 159 | 160 | return $hotkeys; 161 | } 162 | 163 | function hook_hotkey_info($hotkeys) { 164 | 165 | $offset = 1 + array_search('open_in_new_window', array_keys($hotkeys[__('Article')])); 166 | $hotkeys[__('Article')] = 167 | array_slice($hotkeys[__('Article')], 0, $offset, true) + 168 | array('pock_it' => __('Save to Pocket')) + 169 | array_slice($hotkeys[__('Article')], $offset, NULL, true); 170 | 171 | return $hotkeys; 172 | } 173 | 174 | } 175 | 176 | 177 | ?> 178 | -------------------------------------------------------------------------------- /pocket.js: -------------------------------------------------------------------------------- 1 | Plugins.oneclickpocket = { 2 | 3 | shareArticleToPocket: function(id, btn) { 4 | try { 5 | 6 | var d = new Date(); 7 | var ts = d.getTime(); 8 | 9 | Notify.progress("Saving to Pocket…", true); 10 | xhrPost("backend.php", 11 | { 12 | op: "pluginhandler", 13 | plugin: "oneclickpocket", 14 | method: "getInfo", 15 | id: encodeURIComponent(id) 16 | }, 17 | (transport) => { 18 | var ti = JSON.parse(transport.responseText); 19 | if (ti.status=="1") { 20 | Notify.info("Saved to Pocket:
" + ti.title + ""); 21 | btn.src='plugins/oneclickpocket/pocket.png'; 22 | btn.title='Saved to Pocket'; 23 | } 24 | else { 25 | Notify.error("Error saving to Pocket!
("+ti.status+")"); 26 | } 27 | } 28 | ); 29 | 30 | } catch (e) { 31 | App.Error.report(e); 32 | } 33 | } 34 | }; 35 | 36 | require(['dojo/_base/kernel', 'dojo/ready'], function (dojo, ready) { 37 | ready(function () { 38 | PluginHost.register(PluginHost.HOOK_INIT_COMPLETE, () => { 39 | App.hotkey_actions['pock_it'] = function() { 40 | if (Article.getActive()) { 41 | var artid = "ocp"+Article.getActive(); 42 | Plugins.oneclickpocket.shareArticleToPocket(Article.getActive(), document.getElementById(artid)); 43 | return; 44 | } 45 | }; 46 | }); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /pocket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fxneumann/oneclickpocket/b2961105949c25098afe20d4faae28f6371d4043/pocket.png -------------------------------------------------------------------------------- /pocketgrey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fxneumann/oneclickpocket/b2961105949c25098afe20d4faae28f6371d4043/pocketgrey.png --------------------------------------------------------------------------------