diff options
Diffstat (limited to 'plugins')
65 files changed, 1223 insertions, 2518 deletions
diff --git a/plugins/af_buttersafe/init.php b/plugins/af_buttersafe/init.php index c9f6505cd..05e684aa0 100644 --- a/plugins/af_buttersafe/init.php +++ b/plugins/af_buttersafe/init.php @@ -1,7 +1,6 @@ <?php class Af_Buttersafe extends Plugin { - private $link; private $host; function about() { @@ -11,7 +10,6 @@ class Af_Buttersafe extends Plugin { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); @@ -55,5 +53,10 @@ class Af_Buttersafe extends Plugin { return $article; } + + function api_version() { + return 2; + } + } ?> diff --git a/plugins/af_explosm/init.php b/plugins/af_explosm/init.php index 2a8fab491..dd106653a 100644 --- a/plugins/af_explosm/init.php +++ b/plugins/af_explosm/init.php @@ -1,7 +1,6 @@ <?php class Af_Explosm extends Plugin { - private $link; private $host; function about() { @@ -11,7 +10,6 @@ class Af_Explosm extends Plugin { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); @@ -55,5 +53,9 @@ class Af_Explosm extends Plugin { return $article; } + + function api_version() { + return 2; + } } ?> diff --git a/plugins/af_gocomics/init.php b/plugins/af_gocomics/init.php index 466ec9687..e95de9f14 100644 --- a/plugins/af_gocomics/init.php +++ b/plugins/af_gocomics/init.php @@ -1,7 +1,5 @@ <?php class Af_GoComics extends Plugin { - - private $link; private $host; function about() { @@ -11,7 +9,6 @@ class Af_GoComics extends Plugin { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); @@ -55,5 +52,10 @@ class Af_GoComics extends Plugin { return $article; } + + function api_version() { + return 2; + } + } ?> diff --git a/plugins/af_pennyarcade/init.php b/plugins/af_pennyarcade/init.php index 26d19bc01..8ad02e14c 100644 --- a/plugins/af_pennyarcade/init.php +++ b/plugins/af_pennyarcade/init.php @@ -1,17 +1,15 @@ <?php class Af_PennyArcade extends Plugin { - private $link; private $host; function about() { - return array(1.0, + return array(1.1, "Strip unnecessary stuff from PA feeds", "fox"); } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); @@ -23,27 +21,57 @@ class Af_PennyArcade extends Plugin { if (strpos($article["link"], "penny-arcade.com") !== FALSE && strpos($article["title"], "Comic:") !== FALSE) { if (strpos($article["plugin_data"], "pennyarcade,$owner_uid:") === FALSE) { + if ($debug_enabled) { + _debug("af_pennyarcade: Processing comic"); + } + $doc = new DOMDocument(); - @$doc->loadHTML(fetch_file_contents($article["link"])); + $doc->loadHTML(fetch_file_contents($article["link"])); $basenode = false; if ($doc) { $xpath = new DOMXPath($doc); - $entries = $xpath->query('(//img[@src])'); // we might also check for img[@class='strip'] I guess... - - $matches = array(); + $entries = $xpath->query('(//div[@class="post comic"])'); foreach ($entries as $entry) { + $basenode = $entry; + } + + if ($basenode) { + $article["content"] = $doc->saveXML($basenode); + $article["plugin_data"] = "pennyarcade,$owner_uid:" . $article["plugin_data"]; + } + } + } else if (isset($article["stored"]["content"])) { + $article["content"] = $article["stored"]["content"]; + } + } - if (preg_match("/(http:\/\/art.penny-arcade.com\/.*)/i", $entry->getAttribute("src"), $matches)) { + if (strpos($article["link"], "penny-arcade.com") !== FALSE && strpos($article["title"], "News Post:") !== FALSE) { + if (strpos($article["plugin_data"], "pennyarcade,$owner_uid:") === FALSE) { + if ($debug_enabled) { + _debug("af_pennyarcade: Processing news post"); + } + $doc = new DOMDocument(); + $doc->loadHTML(fetch_file_contents($article["link"])); + + if ($doc) { + $xpath = new DOMXPath($doc); + $entries = $xpath->query('(//div[@class="post"])'); + + $basenode = false; - $basenode = $entry; - break; - } + foreach ($entries as $entry) { + $basenode = $entry; } - if ($basenode) { + $uninteresting = $xpath->query('(//div[@class="heading"])'); + foreach ($uninteresting as $i) { + $i->parentNode->removeChild($i); + } + + if ($basenode){ $article["content"] = $doc->saveXML($basenode); $article["plugin_data"] = "pennyarcade,$owner_uid:" . $article["plugin_data"]; } @@ -55,5 +83,10 @@ class Af_PennyArcade extends Plugin { return $article; } + + function api_version() { + return 2; + } + } ?> diff --git a/plugins/af_redditimgur/init.php b/plugins/af_redditimgur/init.php index 2bb44f6d3..39a20784c 100644 --- a/plugins/af_redditimgur/init.php +++ b/plugins/af_redditimgur/init.php @@ -1,7 +1,5 @@ <?php class Af_RedditImgur extends Plugin { - - private $link; private $host; function about() { @@ -11,7 +9,6 @@ class Af_RedditImgur extends Plugin { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); @@ -40,7 +37,9 @@ class Af_RedditImgur extends Plugin { $img = $doc->createElement('img'); $img->setAttribute("src", $entry->getAttribute("href")); - $entry->parentNode->replaceChild($img, $entry); + $br = $doc->createElement('br'); + $entry->parentNode->insertBefore($img, $entry); + $entry->parentNode->insertBefore($br, $entry); $found = true; } @@ -66,7 +65,12 @@ class Af_RedditImgur extends Plugin { if (preg_match("/^http:\/\/i.imgur.com\/$token\./", $aentry->getAttribute("src"))) { $img = $doc->createElement('img'); $img->setAttribute("src", $aentry->getAttribute("src")); + + $br = $doc->createElement('br'); + $entry->parentNode->insertBefore($img, $entry); + $entry->parentNode->insertBefore($br, $entry); + $found = true; break; @@ -94,7 +98,12 @@ class Af_RedditImgur extends Plugin { $img = $doc->createElement('img'); $img->setAttribute("src", $aentry->getAttribute("href")); $entry->parentNode->insertBefore($doc->createElement('br'), $entry); + + $br = $doc->createElement('br'); + $entry->parentNode->insertBefore($img, $entry); + $entry->parentNode->insertBefore($br, $entry); + $found = true; } } @@ -124,5 +133,10 @@ class Af_RedditImgur extends Plugin { return $article; } + + function api_version() { + return 2; + } + } ?> diff --git a/plugins/af_unburn/init.php b/plugins/af_unburn/init.php index b68796fb4..a97502b12 100644 --- a/plugins/af_unburn/init.php +++ b/plugins/af_unburn/init.php @@ -1,7 +1,5 @@ <?php class Af_Unburn extends Plugin { - - private $link; private $host; function about() { @@ -11,7 +9,6 @@ class Af_Unburn extends Plugin { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); @@ -29,11 +26,16 @@ class Af_Unburn extends Plugin { if (strpos($article["plugin_data"], "unburn,$owner_uid:") === FALSE) { - $ch = curl_init($article["link"]); + if (ini_get("safe_mode") || ini_get("open_basedir")) { + $ch = curl_init(geturl($article["link"])); + } else { + $ch = curl_init($article["link"]); + } + curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, !ini_get("safe_mode") && !ini_get("open_basedir")); curl_setopt($ch, CURLOPT_USERAGENT, SELF_USER_AGENT); $contents = @curl_exec($ch); @@ -74,5 +76,59 @@ class Af_Unburn extends Plugin { return $article; } + + function geturl($url){ + + (function_exists('curl_init')) ? '' : die('cURL Must be installed for geturl function to work. Ask your host to enable it or uncomment extension=php_curl.dll in php.ini'); + + $curl = curl_init(); + $header[0] = "Accept: text/xml,application/xml,application/xhtml+xml,"; + $header[0] .= "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"; + $header[] = "Cache-Control: max-age=0"; + $header[] = "Connection: keep-alive"; + $header[] = "Keep-Alive: 300"; + $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7"; + $header[] = "Accept-Language: en-us,en;q=0.5"; + $header[] = "Pragma: "; + + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0 Firefox/5.0'); + curl_setopt($curl, CURLOPT_HTTPHEADER, $header); + curl_setopt($curl, CURLOPT_HEADER, true); + curl_setopt($curl, CURLOPT_REFERER, $url); + curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate'); + curl_setopt($curl, CURLOPT_AUTOREFERER, true); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); //CURLOPT_FOLLOWLOCATION Disabled... + curl_setopt($curl, CURLOPT_TIMEOUT, 60); + + $html = curl_exec($curl); + + $status = curl_getinfo($curl); + curl_close($curl); + + if($status['http_code']!=200){ + if($status['http_code'] == 301 || $status['http_code'] == 302) { + list($header) = explode("\r\n\r\n", $html, 2); + $matches = array(); + preg_match("/(Location:|URI:)[^(\n)]*/", $header, $matches); + $url = trim(str_replace($matches[1],"",$matches[0])); + $url_parsed = parse_url($url); + return (isset($url_parsed))? geturl($url):''; + } + $oline=''; + foreach($status as $key=>$eline){$oline.='['.$key.']'.$eline.' ';} + $line =$oline." \r\n ".$url."\r\n-----------------\r\n"; + $handle = @fopen('./curl.error.log', 'a'); + fwrite($handle, $line); + return FALSE; + } + return $url; + } + + function api_version() { + return 2; + } + } ?> diff --git a/plugins/auth_imap/init.php b/plugins/auth_imap/init.php deleted file mode 100644 index cca279cb3..000000000 --- a/plugins/auth_imap/init.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php -/* Requires php-imap - Put the following options in config.php: - - define('IMAP_AUTH_SERVER', 'your.imap.server:port'); - define('IMAP_AUTH_OPTIONS', '/tls/novalidate-cert/norsh'); - // More about options: http://php.net/manual/ru/function.imap-open.php - -*/ -class Auth_Imap extends Plugin implements IAuthModule { - - private $link; - private $host; - private $base; - - function about() { - return array(1.0, - "Authenticates against an IMAP server (configured in config.php)", - "fox", - true); - } - - function init($host) { - $this->link = $host->get_link(); - $this->host = $host; - $this->base = new Auth_Base($this->link); - - $host->add_hook($host::HOOK_AUTH_USER, $this); - } - - function authenticate($login, $password) { - - if ($login && $password) { - $imap = imap_open( - "{".IMAP_AUTH_SERVER.IMAP_AUTH_OPTIONS."}INBOX", - $login, - $password); - - if ($imap) { - imap_close($imap); - - return $this->base->auto_create_user($login); - } - } - - return false; - } - -} - -?> diff --git a/plugins/auth_internal/init.php b/plugins/auth_internal/init.php index cf6c13780..87c8555c0 100644 --- a/plugins/auth_internal/init.php +++ b/plugins/auth_internal/init.php @@ -1,7 +1,5 @@ <?php class Auth_Internal extends Plugin implements IAuthModule { - - private $link; private $host; function about() { @@ -12,7 +10,6 @@ class Auth_Internal extends Plugin implements IAuthModule { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_AUTH_USER, $this); @@ -25,12 +22,14 @@ class Auth_Internal extends Plugin implements IAuthModule { $login = db_escape_string($login); $otp = db_escape_string($_REQUEST["otp"]); - if (get_schema_version($this->link) > 96) { + if (get_schema_version() > 96) { if (!defined('AUTH_DISABLE_OTP') || !AUTH_DISABLE_OTP) { - $result = db_query($this->link, "SELECT otp_enabled,salt FROM ttrss_users WHERE + + $result = db_query("SELECT otp_enabled,salt FROM ttrss_users WHERE login = '$login'"); if (db_num_rows($result) > 0) { + require_once "lib/otphp/vendor/base32.php"; require_once "lib/otphp/lib/otp.php"; require_once "lib/otphp/lib/totp.php"; @@ -52,17 +51,18 @@ class Auth_Internal extends Plugin implements IAuthModule { $return = urlencode($_REQUEST["return"]); ?><html> <head><title>Tiny Tiny RSS</title></head> - <body> + <?php stylesheet_tag("utility.css") ?> + <body class="otp"><div class="content"> <form action="public.php?return=<?php echo $return ?>" - method="POST"> + method="POST" class="otpform"> <input type="hidden" name="op" value="login"> <input type="hidden" name="login" value="<?php echo htmlspecialchars($login) ?>"> <input type="hidden" name="password" value="<?php echo htmlspecialchars($password) ?>"> <label><?php echo __("Please enter your one time password:") ?></label> - <input type="password" size="6" name="otp"/> + <input autocomplete="off" size="6" name="otp" value=""/> <input type="submit" value="Continue"/> - </form> + </form></div> <script type="text/javascript"> document.forms[0].otp.focus(); </script> @@ -74,9 +74,9 @@ class Auth_Internal extends Plugin implements IAuthModule { } } - if (get_schema_version($this->link) > 87) { + if (get_schema_version() > 87) { - $result = db_query($this->link, "SELECT salt FROM ttrss_users WHERE + $result = db_query("SELECT salt FROM ttrss_users WHERE login = '$login'"); if (db_num_rows($result) != 1) { @@ -94,7 +94,7 @@ class Auth_Internal extends Plugin implements IAuthModule { // verify and upgrade password to new salt base - $result = db_query($this->link, $query); + $result = db_query($query); if (db_num_rows($result) == 1) { // upgrade password to MODE2 @@ -102,7 +102,7 @@ class Auth_Internal extends Plugin implements IAuthModule { $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $pwd_hash = encrypt_password($password, $salt, true); - db_query($this->link, "UPDATE ttrss_users SET + db_query("UPDATE ttrss_users SET pwd_hash = '$pwd_hash', salt = '$salt' WHERE login = '$login'"); $query = "SELECT id @@ -130,7 +130,7 @@ class Auth_Internal extends Plugin implements IAuthModule { pwd_hash = '$pwd_hash2')"; } - $result = db_query($this->link, $query); + $result = db_query($query); if (db_num_rows($result) == 1) { return db_fetch_result($result, 0, "id"); @@ -142,7 +142,7 @@ class Auth_Internal extends Plugin implements IAuthModule { function check_password($owner_uid, $password) { $owner_uid = db_escape_string($owner_uid); - $result = db_query($this->link, "SELECT salt,login FROM ttrss_users WHERE + $result = db_query("SELECT salt,login FROM ttrss_users WHERE id = '$owner_uid'"); $salt = db_fetch_result($result, 0, "salt"); @@ -163,7 +163,7 @@ class Auth_Internal extends Plugin implements IAuthModule { id = '$owner_uid' AND pwd_hash = '$password_hash'"; } - $result = db_query($this->link, $query); + $result = db_query($query); return db_num_rows($result) != 0; } @@ -176,7 +176,7 @@ class Auth_Internal extends Plugin implements IAuthModule { $new_salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $new_password_hash = encrypt_password($new_password, $new_salt, true); - db_query($this->link, "UPDATE ttrss_users SET + db_query("UPDATE ttrss_users SET pwd_hash = '$new_password_hash', salt = '$new_salt', otp_enabled = false WHERE id = '$owner_uid'"); @@ -187,5 +187,10 @@ class Auth_Internal extends Plugin implements IAuthModule { return "ERROR: ".__('Old password is incorrect.'); } } + + function api_version() { + return 2; + } + } ?> diff --git a/plugins/auth_remote/init.php b/plugins/auth_remote/init.php index 65f188b8f..2ec2c87b2 100644 --- a/plugins/auth_remote/init.php +++ b/plugins/auth_remote/init.php @@ -1,7 +1,6 @@ <?php class Auth_Remote extends Plugin implements IAuthModule { - private $link; private $host; private $base; @@ -13,9 +12,8 @@ class Auth_Remote extends Plugin implements IAuthModule { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; - $this->base = new Auth_Base($this->link); + $this->base = new Auth_Base(); $host->add_hook($host::HOOK_AUTH_USER, $this); } @@ -24,7 +22,7 @@ class Auth_Remote extends Plugin implements IAuthModule { $cert_serial = db_escape_string(get_ssl_certificate_id()); if ($cert_serial) { - $result = db_query($this->link, "SELECT login FROM ttrss_user_prefs, ttrss_users + $result = db_query("SELECT login FROM ttrss_user_prefs, ttrss_users WHERE pref_name = 'SSL_CERT_SERIAL' AND value = '$cert_serial' AND owner_uid = ttrss_users.id"); @@ -40,11 +38,14 @@ class Auth_Remote extends Plugin implements IAuthModule { function authenticate($login, $password) { $try_login = db_escape_string($_SERVER["REMOTE_USER"]); + // php-cgi + if (!$try_login) $try_login = db_escape_string($_SERVER["REDIRECT_REMOTE_USER"]); + if (!$try_login) $try_login = $this->get_login_by_ssl_certificate(); # if (!$try_login) $try_login = "test_qqq"; if ($try_login) { - $user_id = $this->base->auto_create_user($try_login); + $user_id = $this->base->auto_create_user($try_login, $password); if ($user_id) { $_SESSION["fake_login"] = $try_login; @@ -58,14 +59,14 @@ class Auth_Remote extends Plugin implements IAuthModule { $fullname = $_SERVER['HTTP_USER_NAME'] ? $_SERVER['HTTP_USER_NAME'] : $_SERVER['AUTHENTICATE_CN']; if ($fullname){ $fullname = db_escape_string($fullname); - db_query($this->link, "UPDATE ttrss_users SET full_name = '$fullname' WHERE id = " . + db_query("UPDATE ttrss_users SET full_name = '$fullname' WHERE id = " . $user_id); } // update user mail $email = $_SERVER['HTTP_USER_MAIL'] ? $_SERVER['HTTP_USER_MAIL'] : $_SERVER['AUTHENTICATE_MAIL']; if ($email){ $email = db_escape_string($email); - db_query($this->link, "UPDATE ttrss_users SET email = '$email' WHERE id = " . + db_query("UPDATE ttrss_users SET email = '$email' WHERE id = " . $user_id); } } @@ -76,6 +77,11 @@ class Auth_Remote extends Plugin implements IAuthModule { return false; } + + function api_version() { + return 2; + } + } ?> diff --git a/plugins/bookmarklets/init.php b/plugins/bookmarklets/init.php index 22f4f05a7..4c4d95d49 100644 --- a/plugins/bookmarklets/init.php +++ b/plugins/bookmarklets/init.php @@ -1,6 +1,5 @@ <?php class Bookmarklets extends Plugin { - private $link; private $host; function about() { @@ -10,7 +9,6 @@ class Bookmarklets extends Plugin { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_PREFS_TAB, $this); @@ -21,7 +19,7 @@ class Bookmarklets extends Plugin { print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Bookmarklets')."\">"; - print "<p>" . __("Drag the link below to your browser toolbar, open the feed you're interested in in your browser and click on the link to subscribe to it.") . "</p>"; + print_notice(__("Drag the link below to your browser toolbar, open the feed you're interested in in your browser and click on the link to subscribe to it.")); $bm_subscribe_url = str_replace('%s', '', add_feed_url()); @@ -29,19 +27,28 @@ class Bookmarklets extends Plugin { $bm_url = htmlspecialchars("javascript:{if(confirm('$confirm_str'.replace('%s',window.location.href)))window.location.href='$bm_subscribe_url'+window.location.href}"); + print "<p>"; print "<a href=\"$bm_url\" class='bookmarklet'>" . __('Subscribe in Tiny Tiny RSS'). "</a>"; + print "</p>"; - print "<p>" . __("Use this bookmarklet to publish arbitrary pages using Tiny Tiny RSS") . "</p>"; + print_notice(__("Use this bookmarklet to publish arbitrary pages using Tiny Tiny RSS")); + + print "<p>"; $bm_url = htmlspecialchars("javascript:(function(){var d=document,w=window,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),f='".SELF_URL_PATH."/public.php?op=sharepopup',l=d.location,e=encodeURIComponent,g=f+'&title='+((e(s))?e(s):e(document.title))+'&url='+e(l.href);function a(){if(!w.open(g,'t','toolbar=0,resizable=0,scrollbars=1,status=1,width=500,height=250')){l.href=g;}}a();})()"); print "<a href=\"$bm_url\" class='bookmarklet'>" . __('Share with Tiny Tiny RSS'). "</a>"; + print "</p>"; + print "</div>"; #pane } - } + function api_version() { + return 2; + } + } ?> diff --git a/plugins/close_button/init.php b/plugins/close_button/init.php index bf4183320..7911642c3 100644 --- a/plugins/close_button/init.php +++ b/plugins/close_button/init.php @@ -1,10 +1,8 @@ <?php class Close_Button extends Plugin { - private $link; private $host; function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); @@ -17,8 +15,8 @@ class Close_Button extends Plugin { } function hook_article_button($line) { - if (!get_pref($this->link, "COMBINED_DISPLAY_MODE")) { - $rv = "<img src=\"".theme_image($this->link, 'plugins/close_button/button.png')."\" + if (!get_pref("COMBINED_DISPLAY_MODE")) { + $rv = "<img src=\"plugins/close_button/button.png\" class='tagsPic' style=\"cursor : pointer\" onclick=\"closeArticlePanel()\" title='".__('Close article')."'>"; @@ -26,5 +24,10 @@ class Close_Button extends Plugin { return $rv; } + + function api_version() { + return 2; + } + } ?> diff --git a/plugins/digest/digest.css b/plugins/digest/digest.css deleted file mode 100644 index 54568e3bc..000000000 --- a/plugins/digest/digest.css +++ /dev/null @@ -1,337 +0,0 @@ -body#ttrssDigest { - color : black; - font-family : sans-serif; - font-size : 12px; - margin : 0px; - background : url("images/tile.png"); -} - -a { - color : #0069D8; - text-decoration : none; -} - -a:hover { - color : gray; -} - -#header a, #footer a { - color : gray; -} - -#header a:hover, #footer a:hover { - color : #0069D8; -} - -#header { - font-size : 13px; - font-family : "Segoe UI", Tahoma, sans-serif; - padding : 5px 5px 5px 1.5em; - color : gray; - position : absolute; - top : 0px; - height : 30px; - left : 0px; - right : 0px; - color : #a0a0a0; -} - -#header span.title { - font-weight : bold; - font-style : italic; -} - -#header div.links { - position : absolute; - right : 1.5em; -} - -#search { - float : right; - clear : left; - -} - -#title { -} - -#latest { - padding : 5px; -} - -#content { - position : absolute; - left : 0px; - top : 30px; - right : 0px; - bottom : 0px; - -webkit-transition: left 0.2s linear, right 0.2s linear; - -moz-transition: left 0.2s linear, right 0.2s linear; - transition: left 0.2s linear, right 0.2s linear; -} - -#article { - position : absolute; - overflow : auto; - right : 0px; - width : 60%; - bottom : 0px; - top : 30px; - background : white; - z-index : -1; - opacity : 0; - -webkit-transition: opacity 0.2s linear; - -moz-transition: opacity 0.2s linear; - transition: opacity 0.2s linear; -} - -#article.visible { - opacity : 1; -} - -#article #article-content h1 { - margin : 0px 0px 10px 0px; - padding : 0px 0px 5px 0px; - font-family : "Segoe UI", Tahoma, sans-serif; - font-size : 21px; - font-weight : bold; - border-width : 0px 0px 3px 0px; - border-style : solid; - border-color : #e0e0e0; - color : gray; -} - -#article #article-content #toolbar { - border-width : 0px 0px 1px 0px; - border-color : #e0e0e0; - border-style : solid; - background : #fafafa; - font-size : 14px; - font-weight : bold; - padding : 5px 10px 5px 10px; - margin : 0px 0px 0px 0px; -} - -#article #article-content { - padding : 0px; - font-size : 16px; -} - -#article #article-content #tags { - color : #a0a0a0; -} - -#article #article-content #ops { - float : right; -} - -#article #article-content #ops img { - cursor : pointer; - margin-right : 0px; - margin-left : 10px; -} - -#article #article-content #inner { - padding : 20px; -} - -#article #article-content img { - max-width : 90%; -} - -#content.move { - left : -300px; - right : 60% -} - -#feeds { - position : absolute; - left : 0px; - width : 300px; - top : -30px; - bottom : 0px; - font-size : 14px; - overflow : auto; - border-width : 0px 3px 0px 0px; - border-color : #88b0f0; - border-style : solid; - background : #eee; -} - -#feeds ul#feeds-content img { - width : 16px; - height : 16px; - vertical-align : middle; - margin-right : 5px; -} - -#feeds ul#feeds-content div.unread-ctr { - color : #d0d0d0; - padding-left : 10px; - float : right; -} - -#feeds ul#feeds-content li { - padding : 10px; - clear : both; - cursor : pointer; - color : #303030; - white-space : nowrap; -} - -#feeds ul#feeds-content li.selected { - background : white; -} - -#feeds ul#feeds-content { - list-style-type : none; - font-weight : bold; - margin : 0px; - padding : 0px; -} - -#headlines { - font-size : 14px; - position : absolute; - left : 303px; - top : 0px; - bottom : 0px; - right : 0px; - overflow : auto; - border-width : 0px 3px 0px 0px; - border-style : solid; - border-color : #88b0f0; -} - -#headlines h1 a { - color : #684C99; -} - -#headlines ul#headlines-content .cb { - vertical-align : middle; - margin-right : 5px; - float : left; -} - -#headlines ul#headlines-content img.icon { - width : 16px; - height : 16px; - vertical-align : middle; - margin-right : 5px; - float : right; -} - -#headlines ul#headlines-content { - list-style-type : none; - color : gray; - margin : 0px; - padding : 0px; -} - -#headlines ul#headlines-content li { - margin : 0px 0px 0px 0px; - padding : 10px; - color : gray; - clear : left; - border-width : 0px 0px 1px 0px; - border-style : solid; - border-color : #e0e0e0; - background : #eee; -} - -#headlines ul#headlines-content a.title { - font-size : 14px; - font-weight : bold; - display : block; - margin-left : 21px; - position : relative; -} - -#headlines ul#headlines-content li.fresh a.title { - color : #007FFF; -} - -#headlines ul#headlines-content li.unread a.title { - color : black; - /* color : #8DB1D6; */ -} - -#headlines ul#headlines-content li.read a.title { - color : gray; -} - -#headlines ul#headlines-content li.unread, -#headlines ul#headlines-content li.fresh { - background-color : white; -} - -#headlines ul#headlines-content li.selected { - background-color : #fff7d5; - border-color : white white #e0e0e0; -} - -#headlines ul#headlines-content img#H-LOADING-IMG { - margin-left : 5px; -} - -#headlines ul#headlines-content div.excerpt { - color : #404040; - cursor : pointer; - margin-top : 5px; -} - -#headlines ul#headlines-content div.content { - color : #404040; -} - -#headlines ul#headlines-content div.content img { - max-width : 75%; -} - -#headlines ul#headlines-content div.body { - margin-left : 21px; - /*margin-left : 42px;*/ -} - -#headlines ul#headlines-content div.info { - font-size : 11px; - margin-top : 5px; -} - -#headlines ul#headlines-content div.info a { - color : gray; -} - -#overlay { - background : white; - left : 0; - top : 0; - height : 100%; - width : 100%; - z-index : 100; - position : absolute; - text-align : center; -} - -#overlay_inner { - margin : 1em; -} - -#overlay img { - vertical-align : middle; -} - -div.fatalError button { - margin-top : 5px; -} - -div.fatalError textarea { - width : 100%; - height : 100px; -} - -div.insensitive { - color : gray; -} - - diff --git a/plugins/digest/digest.js b/plugins/digest/digest.js deleted file mode 100644 index 88410d9ed..000000000 --- a/plugins/digest/digest.js +++ /dev/null @@ -1,906 +0,0 @@ -var last_feeds = []; -var init_params = {}; -var hotkeys_map = false; -var hotkey_prefix = false; - -var _active_feed_id = false; -var _update_timeout = false; -var _view_update_timeout = false; -var _feedlist_expanded = false; -var _update_seq = 1; - -function article_appear(article_id) { - try { - new Effect.Appear('A-' + article_id); - } catch (e) { - exception_error("article_appear", e); - } -} - -function catchup_feed(feed_id, callback) { - try { - - var fn = find_feed(last_feeds, feed_id).title; - - if (confirm(__("Mark all articles in %s as read?").replace("%s", fn))) { - - var is_cat = ""; - - if (feed_id < 0) is_cat = "true"; // KLUDGE - - var query = "?op=rpc&method=catchupFeed&feed_id=" + - feed_id + "&is_cat=" + is_cat; - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - if (callback) callback(transport); - - update(); - } }); - } - - } catch (e) { - exception_error("catchup_article", e); - } -} - -function get_visible_article_ids() { - try { - var elems = $("headlines-content").getElementsByTagName("LI"); - var ids = []; - - for (var i = 0; i < elems.length; i++) { - if (elems[i].id && elems[i].id.match("A-")) { - ids.push(elems[i].id.replace("A-", "")); - } - } - - return ids; - - } catch (e) { - exception_error("get_visible_article_ids", e); - } -} - -function catchup_visible_articles(callback) { - try { - - var ids = get_visible_article_ids(); - - if (confirm(__("Mark %d displayed articles as read?").replace("%d", ids.length))) { - - var query = "?op=rpc&method=catchupSelected" + - "&cmode=0&ids=" + param_escape(ids); - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - if (callback) callback(transport); - - viewfeed(_active_feed_id, 0); - } }); - - } - - } catch (e) { - exception_error("catchup_visible_articles", e); - } -} - -function catchup_article(article_id, callback) { - try { - var query = "?op=rpc&method=catchupSelected" + - "&cmode=0&ids=" + article_id; - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - if (callback) callback(transport); - } }); - - } catch (e) { - exception_error("catchup_article", e); - } -} - -function set_selected_article(article_id) { - try { - $$("#headlines-content > li[id*=A-]").each(function(article) { - var id = article.id.replace("A-", ""); - - var cb = article.getElementsByTagName("INPUT")[0]; - - if (id == article_id) { - article.addClassName("selected"); - cb.checked = true; - } else { - article.removeClassName("selected"); - cb.checked = false; - } - - }); - - } catch (e) { - exception_error("mark_selected_feed", e); - } -} - - -function set_selected_feed(feed_id) { - try { - var feeds = $("feeds-content").getElementsByTagName("LI"); - - for (var i = 0; i < feeds.length; i++) { - if (feeds[i].id == "F-" + feed_id) - feeds[i].className = "selected"; - else - feeds[i].className = ""; - } - - _active_feed_id = feed_id; - - } catch (e) { - exception_error("mark_selected_feed", e); - } -} - -function load_more() { - try { - var pr = $("H-LOADING-IMG"); - - if (pr) Element.show(pr); - - var offset = $$("#headlines-content > li[id*=A-][class*=fresh],li[id*=A-][class*=unread]").length; - - viewfeed(false, offset, false, false, true, - function() { - var pr = $("H-LOADING-IMG"); - - if (pr) Element.hide(pr); - }); - } catch (e) { - exception_error("load_more", e); - } -} - -function update(callback) { - try { - console.log('updating feeds...'); - - window.clearTimeout(_update_timeout); - - new Ajax.Request("backend.php", { - parameters: "?op=digest&method=digestinit", - onComplete: function(transport) { - fatal_error_check(transport); - parse_feeds(transport); - set_selected_feed(_active_feed_id); - - if (callback) callback(transport); - } }); - - _update_timeout = window.setTimeout('update()', 5*1000); - } catch (e) { - exception_error("update", e); - } -} - -function remove_headline_entry(article_id) { - try { - var elem = $('A-' + article_id); - - if (elem) { - elem.parentNode.removeChild(elem); - } - - } catch (e) { - exception_error("remove_headline_entry", e); - } -} - -function view_update() { - try { - viewfeed(_active_feed_id, _active_feed_offset, false, true, true); - update(); - } catch (e) { - exception_error("view_update", e); - } -} - -function view(article_id) { - try { - $("content").addClassName("move"); - - var a = $("A-" + article_id); - var h = $("headlines"); - - setTimeout(function() { - // below or above viewport, reposition headline - if (a.offsetTop > h.scrollTop + h.offsetHeight || a.offsetTop+a.offsetHeight < h.scrollTop+a.offsetHeight) - h.scrollTop = a.offsetTop - (h.offsetHeight/2 - a.offsetHeight/2); - }, 500); - - new Ajax.Request("backend.php", { - parameters: "?op=digest&method=digestgetcontents&article_id=" + - article_id, - onComplete: function(transport) { - fatal_error_check(transport); - - var reply = JSON.parse(transport.responseText); - - if (reply) { - var article = reply['article']; - - var mark_part = ""; - var publ_part = ""; - - var tags_part = ""; - - if (article.tags.length > 0) { - tags_part = " " + __("in") + " "; - - for (var i = 0; i < Math.min(5, article.tags.length); i++) { - //tags_part += "<a href=\"#\" onclick=\"viewfeed('" + - // article.tags[i] + "')\">" + - // article.tags[i] + "</a>, "; - - tags_part += article.tags[i] + ", "; - } - - tags_part = tags_part.replace(/, $/, ""); - tags_part = "<span class=\"tags\">" + tags_part + "</span>"; - - } - - if (article.marked) - mark_part = "<img title='"+ __("Unstar article")+"' onclick=\"toggle_mark(this, "+article.id+")\" src='images/mark_set.svg'>"; - else - mark_part = "<img title='"+__("Star article")+"' onclick=\"toggle_mark(this, "+article.id+")\" src='images/mark_unset.svg'>"; - - if (article.published) - publ_part = "<img title='"+__("Unpublish article")+"' onclick=\"toggle_pub(this, "+article.id+")\" src='images/pub_set.svg'>"; - else - publ_part = "<img title='"+__("Publish article")+"' onclick=\"toggle_pub(this, "+article.id+")\" src='images/pub_unset.svg'>"; - - var tmp = "<div id=\"inner\">" + - "<div id=\"ops\">" + - mark_part + - publ_part + - "</div>" + - "<h1>" + "<a target=\"_blank\" href=\""+article.url+"\">" + - article.title + "</a>" + "</h1>" + - "<div id=\"tags\">" + - tags_part + - "</div>" + - article.content + "</div>"; - - $("article-content").innerHTML = tmp; - $("article").addClassName("visible"); - - set_selected_article(article.id); - - catchup_article(article_id, - function() { - $("A-" + article_id).addClassName("read"); - }); - - } else { - elem.innerHTML = __("Error: unable to load article."); - } - } - }); - - - return false; - } catch (e) { - exception_error("view", e); - } -} - -function close_article() { - $("content").removeClassName("move"); - $("article").removeClassName("visible"); -} - -function viewfeed(feed_id, offset, replace, no_effects, no_indicator, callback) { - try { - - if (!feed_id) feed_id = _active_feed_id; - if (offset == undefined) offset = 0; - if (replace == undefined) replace = (offset == 0); - - _update_seq = _update_seq + 1; - - if (!offset) $("headlines").scrollTop = 0; - - var query = "backend.php?op=digest&method=digestupdate&feed_id=" + - param_escape(feed_id) + "&offset=" + offset + - "&seq=" + _update_seq; - - console.log(query); - - var img = false; - - if ($("F-" + feed_id)) { - img = $("F-" + feed_id).getElementsByTagName("IMG")[0]; - - if (img && !no_indicator) { - img.setAttribute("orig_src", img.src); - img.src = 'images/indicator_tiny.gif'; - } - } - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - Element.hide("overlay"); - - fatal_error_check(transport); - parse_headlines(transport, replace, no_effects); - set_selected_feed(feed_id); - _active_feed_offset = offset; - - if (img && !no_indicator) - img.src = img.getAttribute("orig_src"); - - if (callback) callback(transport); - - } }); - - } catch (e) { - exception_error("view", e); - } -} - -function find_article(articles, article_id) { - try { - for (var i = 0; i < articles.length; i++) { - if (articles[i].id == article_id) - return articles[i]; - } - - return false; - - } catch (e) { - exception_error("find_article", e); - } -} - -function find_feed(feeds, feed_id) { - try { - for (var i = 0; i < feeds.length; i++) { - if (feeds[i].id == feed_id) - return feeds[i]; - } - - return false; - - } catch (e) { - exception_error("find_feed", e); - } -} - -function get_feed_icon(feed) { - try { - if (feed.has_icon) - return getInitParam('icons_url') + "/" + feed.id + '.ico'; - - if (feed.id == -1) - return 'images/mark_set.svg'; - - if (feed.id == -2) - return 'images/pub_set.svg'; - - if (feed.id == -3) - return 'images/fresh.png'; - - if (feed.id == -4) - return 'images/tag.png'; - - if (feed.id < -10) - return 'images/label.png'; - - return 'images/blank_icon.gif'; - - } catch (e) { - exception_error("get_feed_icon", e); - } -} - -function add_feed_entry(feed) { - try { - var icon_part = ""; - - icon_part = "<img src='" + get_feed_icon(feed) + "'/>"; - - var title = (feed.title.length > 30) ? - feed.title.substring(0, 30) + "…" : - feed.title; - - var tmp_html = "<li id=\"F-"+feed.id+"\" onclick=\"viewfeed("+feed.id+")\">" + - "<div class='unread-ctr'>" + "<span class=\"unread\">" + feed.unread + "</span></div>" + - icon_part + title + - "</li>"; - - $("feeds-content").innerHTML += tmp_html; - - - } catch (e) { - exception_error("add_feed_entry", e); - } -} - -function add_headline_entry(article, feed, no_effects) { - try { - - var icon_part = ""; - - icon_part = "<img class='icon' src='" + get_feed_icon(feed) + "'/>"; - - - var style = ""; - - //if (!no_effects) style = "style=\"display : none\""; - - if (article.excerpt.trim() == "") - article.excerpt = __("Click to expand article."); - - var li_class = "unread"; - - var fresh_max = getInitParam("fresh_article_max_age") * 60 * 60; - var d = new Date(); - - if (d.getTime() / 1000 - article.updated < fresh_max) - li_class = "fresh"; - - var checkbox_part = "<input type=\"checkbox\" class=\"cb\" onclick=\"toggle_select_article(this)\"/>"; - - var date = new Date(article.updated * 1000); - - var date_part = date.toString().substring(0,21); - - var tmp_html = "<li id=\"A-"+article.id+"\" "+style+" class=\""+li_class+"\">" + - checkbox_part + - icon_part + - "<a target=\"_blank\" href=\""+article.link+"\""+ - "onclick=\"return view("+article.id+")\" class='title'>" + - article.title + "</a>" + - "<div class='body'>" + - "<div onclick=\"view("+article.id+")\" class='excerpt'>" + - article.excerpt + "</div>" + - "<div onclick=\"view("+article.id+")\" class='info'>"; - -/* tmp_html += "<a href=\#\" onclick=\"viewfeed("+feed.id+")\">" + - feed.title + "</a> " + " @ "; */ - - tmp_html += date_part + "</div>" + - "</div></li>"; - - $("headlines-content").innerHTML += tmp_html; - - if (!no_effects) - window.setTimeout('article_appear(' + article.id + ')', 100); - - } catch (e) { - exception_error("add_headline_entry", e); - } -} - -function expand_feeds() { - try { - _feedlist_expanded = true; - - redraw_feedlist(last_feeds); - - } catch (e) { - exception_error("expand_feeds", e); - } -} - -function redraw_feedlist(feeds) { - try { - - $('feeds-content').innerHTML = ""; - - var limit = 10; - - if (_feedlist_expanded) limit = feeds.length; - - for (var i = 0; i < Math.min(limit, feeds.length); i++) { - add_feed_entry(feeds[i]); - } - - if (feeds.length > limit) { - $('feeds-content').innerHTML += "<li id='F-MORE-PROMPT'>" + - "<img src='images/blank_icon.gif'>" + - "<a href=\"#\" onclick=\"expand_feeds()\">" + - __("%d more...").replace("%d", feeds.length-10) + - "</a>" + "</li>"; - } - - if (feeds.length == 0) { - $('feeds-content').innerHTML = - "<div class='insensitive' style='text-align : center'>" + - __("No unread feeds.") + "</div>"; - } - - if (_active_feed_id) - set_selected_feed(_active_feed_id); - - } catch (e) { - exception_error("redraw_feedlist", e); - } -} - -function parse_feeds(transport) { - try { - var reply = JSON.parse(transport.responseText); - - if (!reply) return; - - var feeds = reply['feeds']; - - if (feeds) { - - feeds.sort( function (a,b) - { - if (b.unread != a.unread) - return (b.unread - a.unread); - else - if (a.title > b.title) - return 1; - else if (a.title < b.title) - return -1; - else - return 0; - }); - - var all_articles = find_feed(feeds, -4); - - update_title(all_articles.unread); - - last_feeds = feeds; - - redraw_feedlist(feeds); - } - - if (reply['hotkeys']) { - hotkeys_map = reply['hotkeys']; - } - - } catch (e) { - console.log(e); - //exception_error("parse_feeds", e); - } -} - -function parse_headlines(transport, replace, no_effects) { - try { - var reply = JSON.parse(transport.responseText); - if (!reply) return; - - var seq = reply['seq']; - - if (seq) { - if (seq != _update_seq) { - console.log("parse_headlines: wrong sequence received."); - return; - } - } else { - return; - } - - var headlines = reply['headlines']['content']; - var headlines_title = reply['headlines']['title']; - - if (headlines && headlines_title) { - - if (replace) { - $('headlines-content').innerHTML = ''; - } - - var pr = $('H-MORE-PROMPT'); - - if (pr) pr.parentNode.removeChild(pr); - - var inserted = false; - - for (var i = 0; i < headlines.length; i++) { - - if (!$('A-' + headlines[i].id)) { - add_headline_entry(headlines[i], - find_feed(last_feeds, headlines[i].feed_id), !no_effects); - - } - } - - console.log(inserted.id); - - var ids = get_visible_article_ids(); - - if (ids.length > 0) { - if (pr) { - $('headlines-content').appendChild(pr); - - } else { - $('headlines-content').innerHTML += "<li id='H-MORE-PROMPT'>" + - "<div class='body'>" + - "<a href=\"#\" onclick=\"catchup_visible_articles()\">" + - __("Mark as read") + "</a> | " + - "<a href=\"javascript:load_more()\">" + - __("Load more...") + "</a>" + - "<img style=\"display : none\" "+ - "id=\"H-LOADING-IMG\" src='images/indicator_tiny.gif'>" + - "</div></li>"; - } - } else { - // FIXME : display some kind of "nothing to see here" prompt here - } - -// if (replace && !no_effects) -// new Effect.Appear('headlines-content', {duration : 0.3}); - - //new Effect.Appear('headlines-content'); - } - - } catch (e) { - exception_error("parse_headlines", e); - } -} - -function init_second_stage() { - try { - new Ajax.Request("backend.php", { - parameters: "backend.php?op=digest&method=digestinit&init=1", - onComplete: function(transport) { - parse_feeds(transport); - Element.hide("overlay"); - - document.onkeydown = hotkey_handler; - - window.setTimeout('viewfeed(-4)', 100); - _update_timeout = window.setTimeout('update()', 5*1000); - } }); - - } catch (e) { - exception_error("init_second_stage", e); - } -} - -function init() { - try { - dojo.require("dijit.Dialog"); - - new Ajax.Request("backend.php", { - parameters: {op: "rpc", method: "sanityCheck"}, - onComplete: function(transport) { - backend_sanity_check_callback(transport); - } }); - - } catch (e) { - exception_error("digest_init", e); - } -} - -function toggle_mark(img, id) { - - try { - - var query = "?op=rpc&id=" + id + "&method=mark"; - - if (!img) return; - - if (img.src.match("mark_unset")) { - img.src = img.src.replace("mark_unset", "mark_set"); - img.alt = __("Unstar article"); - query = query + "&mark=1"; - } else { - img.src = img.src.replace("mark_set", "mark_unset"); - img.alt = __("Star article"); - query = query + "&mark=0"; - } - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - update(); - } }); - - } catch (e) { - exception_error("toggle_mark", e); - } -} - -function toggle_pub(img, id, note) { - - try { - - var query = "?op=rpc&id=" + id + "&method=publ"; - - if (note != undefined) { - query = query + "¬e=" + param_escape(note); - } else { - query = query + "¬e=undefined"; - } - - if (!img) return; - - if (img.src.match("pub_unset") || note != undefined) { - img.src = img.src.replace("pub_unset", "pub_set"); - img.alt = __("Unpublish article"); - query = query + "&pub=1"; - - } else { - img.src = img.src.replace("pub_set", "pub_unset"); - img.alt = __("Publish article"); - query = query + "&pub=0"; - } - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - update(); - } }); - - } catch (e) { - exception_error("toggle_pub", e); - } -} - -function fatal_error(code, msg) { - try { - - if (code == 6) { - window.location.href = "digest.php"; - } else if (code == 5) { - window.location.href = "db-updater.php"; - } else { - - if (msg == "") msg = "Unknown error"; - - console.error("Fatal error: " + code + "\n" + - msg); - - } - - } catch (e) { - exception_error("fatalError", e); - } -} - -function fatal_error_check(transport) { - try { - if (transport.responseXML) { - var error = transport.responseXML.getElementsByTagName("error")[0]; - - if (error) { - var code = error.getAttribute("error-code"); - var msg = error.getAttribute("error-msg"); - if (code != 0) { - fatal_error(code, msg); - return false; - } - } - } - } catch (e) { - exception_error("fatal_error_check", e); - } - return true; -} - -function update_title(unread) { - try { - document.title = "Tiny Tiny RSS"; - - if (unread > 0) - document.title += " (" + unread + ")"; - - } catch (e) { - exception_error("update_title", e); - } -} - -function toggle_select_article(elem) { - try { - var article = elem.parentNode; - - if (article.hasClassName("selected")) - article.removeClassName("selected"); - else - article.addClassName("selected"); - - } catch (e) { - exception_error("toggle_select_article", e); - } -} - -function hotkey_handler(e) { - try { - - if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return; - - var keycode = false; - var shift_key = false; - - var cmdline = $('cmdline'); - - try { - shift_key = e.shiftKey; - } catch (e) { - - } - - if (window.event) { - keycode = window.event.keyCode; - } else if (e) { - keycode = e.which; - } - - var keychar = String.fromCharCode(keycode); - - if (!shift_key) keychar = keychar.toLowerCase(); - - if (keycode == 16) return; // ignore lone shift - if (keycode == 17) return; // ignore lone ctrl - - var hotkey = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")"; - hotkey = hotkey_prefix ? hotkey_prefix + " " + hotkey : hotkey; - hotkey_prefix = false; - - var hotkey_action = false; - var hotkeys = getInitParam("hotkeys"); - - for (sequence in hotkeys[1]) { - if (sequence == hotkey) { - hotkey_action = hotkeys[1][sequence]; - break; - } - } - - switch (keycode) { - case 27: // esc - close_article(); - return false; - } - - switch (hotkey_action) { - case "next_feed": - var feeds = $$("#feeds li"); - for (var i = 0; i < feeds.length; i++) { - var base_id = feeds[i].id.replace("F-", ""); - - if (base_id == _active_feed_id) { - if (feeds[i+1]) { - viewfeed(feeds[i+1].id.replace("F-", "")); - } - break; - } - } - return false; - case "prev_feed": - var feeds = $$("#feeds li"); - for (var i = 0; i < feeds.length; i++) { - var base_id = feeds[i].id.replace("F-", ""); - - if (base_id == _active_feed_id) { - if (feeds[i-1]) { - viewfeed(feeds[i-1].id.replace("F-", "")); - } - break; - } - } - return false; - case "next_article": - return false; - case "prev_article": - return false; - default: - console.log("unhandled action: " + hotkey_action + "; hotkey: " + hotkey); - } - - - } catch (e) { - exception_error("hotkey_handler", e); - } -} diff --git a/plugins/digest/digest_body.php b/plugins/digest/digest_body.php deleted file mode 100644 index c4f51d376..000000000 --- a/plugins/digest/digest_body.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php global $link; ?> - -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - -<html> -<head> - <title>Tiny Tiny RSS</title> - - <link rel="stylesheet" type="text/css" href="lib/dijit/themes/claro/claro.css"/> - <link rel="stylesheet" type="text/css" href="plugins/digest/digest.css?<?php echo $dt_add ?>"/> - - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> - - <?php print_user_stylesheet($link) ?> - - <link rel="shortcut icon" type="image/png" href="images/favicon.png"/> - - <script type="text/javascript" src="lib/dojo/dojo.js" djConfig="parseOnLoad: true"></script> - <script type="text/javascript" src="lib/prototype.js"></script> - <script type="text/javascript" src="lib/scriptaculous/scriptaculous.js?load=effects,dragdrop,controls"></script> - - <script type="text/javascript" charset="utf-8" src="localized_js.php?<?php echo $dt_add ?>"></script> - <script type="text/javascript" charset="utf-8" src="errors.php?mode=js"></script> - <script type="text/javascript" charset="utf-8" src="js/functions.js?<?php echo $dt_add ?>"></script> - <script type="text/javascript" src="plugins/digest/digest.js"></script> - - <script type="text/javascript"> - Event.observe(window, 'load', function() { - init(); - }); - </script> -</head> -<body id="ttrssDigest" class="claro"> - <div id="overlay" style="display : block"> - <div id="overlay_inner"> - <noscript> - <p> - <?php print_error(__("Your browser doesn't support Javascript, which is required - for this application to function properly. Please check your - browser settings.")) ?></p> - </noscript> - - <img src="images/indicator_white.gif"/> - <?php echo __("Loading, please wait...") ?> - </div> - </div> - - <div id="header"> - <a style="float : left" href="#" onclick="close_article()"> - <?php echo __("Back to feeds") ?></a> - - <div class="links"> - - <?php if (!$_SESSION["hide_hello"]) { ?> - <?php echo __('Hello,') ?> <b><?php echo $_SESSION["name"] ?></b> | - <?php } ?> - <?php if (!$_SESSION["hide_logout"]) { ?> - <a href="backend.php?op=logout"><?php echo __('Logout') ?></a> | - <?php } ?> - <a href='<?php echo get_self_url_prefix() ?>/index.php?mobile=false'> - <?php echo __("Regular version") ?></a> - - </div> - </div> - - <div id="article"><div id="article-content"> </div></div> - - <div id="content"> - - <div id="feeds"> - <ul id="feeds-content"> </ul> - </div> - - <div id="headlines"> - <ul id="headlines-content"> </ul> - </div> - </div> - -</body> -</html> diff --git a/plugins/digest/images/tile.png b/plugins/digest/images/tile.png Binary files differdeleted file mode 100644 index 72f2f4553..000000000 --- a/plugins/digest/images/tile.png +++ /dev/null diff --git a/plugins/digest/init.php b/plugins/digest/init.php deleted file mode 100644 index 2feabe3b4..000000000 --- a/plugins/digest/init.php +++ /dev/null @@ -1,110 +0,0 @@ -<?php -// TODO: digest should register digest specific hotkey actions within tt-rss -class Digest extends Plugin implements IHandler { - - private $link; - private $host; - - function about() { - return array(1.0, - "Digest mode for tt-rss (tablet friendly UI)", - "fox", - true); - } - - function init($host) { - $this->link = $host->get_link(); - $this->host = $host; - - $host->add_handler("digest", "*", $this); - } - - function index() { - header("Content-type: text/html; charset=utf-8"); - - login_sequence($this->link); - - global $link; - $link = $this->link; - - require_once dirname(__FILE__) . "/digest_body.php"; - } - - /* function get_js() { - return file_get_contents(dirname(__FILE__) . "/digest.js"); - } */ - - function csrf_ignore($method) { - return in_array($method, array("index")); - } - - function before($method) { - return true; - } - - function after() { - - } - - function digestgetcontents() { - $article_id = db_escape_string($_REQUEST['article_id']); - - $result = db_query($this->link, "SELECT content,title,link,marked,published - FROM ttrss_entries, ttrss_user_entries - WHERE id = '$article_id' AND ref_id = id AND owner_uid = ".$_SESSION['uid']); - - $content = sanitize($this->link, db_fetch_result($result, 0, "content")); - $title = strip_tags(db_fetch_result($result, 0, "title")); - $article_url = htmlspecialchars(db_fetch_result($result, 0, "link")); - $marked = sql_bool_to_bool(db_fetch_result($result, 0, "marked")); - $published = sql_bool_to_bool(db_fetch_result($result, 0, "published")); - - print json_encode(array("article" => - array("id" => $article_id, "url" => $article_url, - "tags" => get_article_tags($this->link, $article_id), - "marked" => $marked, "published" => $published, - "title" => $title, "content" => $content))); - } - - function digestupdate() { - $feed_id = db_escape_string($_REQUEST['feed_id']); - $offset = db_escape_string($_REQUEST['offset']); - $seq = db_escape_string($_REQUEST['seq']); - - if (!$feed_id) $feed_id = -4; - if (!$offset) $offset = 0; - - $reply = array(); - - $reply['seq'] = $seq; - - $headlines = API::api_get_headlines($this->link, $feed_id, 30, $offset, - '', ($feed_id == -4), true, false, "unread", "updated DESC", 0, 0); - - $reply['headlines'] = array(); - $reply['headlines']['title'] = getFeedTitle($this->link, $feed_id); - $reply['headlines']['content'] = $headlines; - - print json_encode($reply); - } - - function digestinit() { - $tmp_feeds = API::api_get_feeds($this->link, -4, true, false, 0); - - $params = array(); - $feeds = array(); - - foreach ($tmp_feeds as $f) { - if ($f['id'] > 0 || $f['id'] == -4) array_push($feeds, $f); - } - - if ($_REQUEST["init"] == 1) { - $params["hotkeys"] = get_hotkeys_map($link); - } - $params["feeds"] = $feeds; - - print json_encode($params); - } - -} -?> diff --git a/plugins/embed_original/button.png b/plugins/embed_original/button.png Binary files differnew file mode 100644 index 000000000..e861201d5 --- /dev/null +++ b/plugins/embed_original/button.png diff --git a/plugins/embed_original/init.css b/plugins/embed_original/init.css new file mode 100644 index 000000000..5fb7e012e --- /dev/null +++ b/plugins/embed_original/init.css @@ -0,0 +1,13 @@ +div.cdmContentInner iframe.embeddedContent { + overflow : auto; + width : 100%; + height : 600px; + border-width : 0px; +} + +div.postContent iframe.embeddedContent { + overflow : auto; + width : 100%; + height : 100%; + border-width : 0px; +} diff --git a/plugins/embed_original/init.js b/plugins/embed_original/init.js new file mode 100644 index 000000000..17090653d --- /dev/null +++ b/plugins/embed_original/init.js @@ -0,0 +1,68 @@ +function embedOriginalArticle(id) { + try { + var hasSandbox = "sandbox" in document.createElement("iframe"); + + if (!hasSandbox) { + alert(__("Sorry, your browser does not support sandboxed iframes.")); + return; + } + + var query = "op=pluginhandler&plugin=embed_original&method=getUrl&id=" + + param_escape(id); + + var c = false; + + if (isCdmMode()) { + c = $$("div#RROW-" + id + " div[class=cdmContentInner]")[0]; + } else if (id == getActiveArticleId()) { + c = $$("div[class=postContent]")[0]; + } + + if (c) { + var iframe = c.parentNode.getElementsByClassName("embeddedContent")[0]; + + if (iframe) { + Element.show(c); + c.parentNode.removeChild(iframe); + + if (isCdmMode()) { + cdmScrollToArticleId(id, true); + } + + return; + } + } + + new Ajax.Request("backend.php", { + parameters: query, + onComplete: function(transport) { + var ti = JSON.parse(transport.responseText); + + if (ti) { + + var iframe = new Element("iframe", { + class: "embeddedContent", + src: ti.url, + width: (c.parentNode.offsetWidth-5)+'px', + height: (c.parentNode.parentNode.offsetHeight-c.parentNode.firstChild.offsetHeight-5)+'px', + style: "overflow: auto; border: none; min-height: "+(document.body.clientHeight/2)+"px;", + sandbox: 'allow-scripts', + }); + + if (c) { + Element.hide(c); + c.parentNode.insertBefore(iframe,c); + + if (isCdmMode()) { + cdmScrollToArticleId(id, true); + } + } + } + + } }); + + + } catch (e) { + exception_error("embedOriginalArticle", e); + } +} diff --git a/plugins/embed_original/init.php b/plugins/embed_original/init.php new file mode 100644 index 000000000..df803d38b --- /dev/null +++ b/plugins/embed_original/init.php @@ -0,0 +1,58 @@ +<?php +class Embed_Original extends Plugin { + private $host; + + function init($host) { + $this->host = $host; + + $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); + } + + function about() { + return array(1.0, + "Try to display original article content inside tt-rss", + "fox"); + } + + function get_js() { + return file_get_contents(dirname(__FILE__) . "/init.js"); + } + + function get_css() { + return file_get_contents(dirname(__FILE__) . "/init.css"); + } + + function hook_article_button($line) { + $id = $line["id"]; + + $rv = "<img src=\"plugins/embed_original/button.png\" + class='tagsPic' style=\"cursor : pointer\" + onclick=\"embedOriginalArticle($id)\" + title='".__('Toggle embed original')."'>"; + + return $rv; + } + + function getUrl() { + $id = db_escape_string($_REQUEST['id']); + + $result = db_query("SELECT link + FROM ttrss_entries, ttrss_user_entries + WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']); + + $url = ""; + + if (db_num_rows($result) != 0) { + $url = db_fetch_result($result, 0, "link"); + + } + + print json_encode(array("url" => $url, "id" => $id)); + } + + function api_version() { + return 2; + } + +} +?> diff --git a/plugins/example/example.js b/plugins/example/example.js deleted file mode 100644 index a31f2c2a2..000000000 --- a/plugins/example/example.js +++ /dev/null @@ -1,3 +0,0 @@ -function example(value) { - alert("Value saved: " + value); -} diff --git a/plugins/example/init.php b/plugins/example/init.php deleted file mode 100644 index f3788ae8c..000000000 --- a/plugins/example/init.php +++ /dev/null @@ -1,82 +0,0 @@ -<?php -class Example extends Plugin { - - // Demonstrates how to add a separate panel to the preferences screen and inject Javascript/save data using Dojo forms. - - private $link; - private $host; - - function about() { - return array(1.0, - "Example plugin #1", - "fox", - true); - } - - function init($host) { - $this->link = $host->get_link(); - $this->host = $host; - - $host->add_hook($host::HOOK_PREFS_TAB, $this); - } - - function save() { - $example_value = db_escape_string($_POST["example_value"]); - - $this->host->set($this, "example", $example_value); - - echo "Value set to $example_value"; - } - - function get_prefs_js() { - return file_get_contents(dirname(__FILE__) . "/example.js"); - } - - function hook_prefs_tab($args) { - if ($args != "prefPrefs") return; - - print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__("Example Pane")."\">"; - - print "<br/>"; - -// print_r($this->host->set($this, "example", rand(0,100))); -// print_r($this->host->get_all($this)); - - $value = $this->host->get($this, "example"); - - print "<form dojoType=\"dijit.form.Form\">"; - - print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\"> - evt.preventDefault(); - if (this.validate()) { - console.log(dojo.objectToQuery(this.getValues())); - new Ajax.Request('backend.php', { - parameters: dojo.objectToQuery(this.getValues()), - onComplete: function(transport) { - notify_info(transport.responseText); - } - }); - //this.reset(); - } - </script>"; - - print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pluginhandler\">"; - print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"save\">"; - print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"plugin\" value=\"example\">"; - - print "<table width=\"100%\" class=\"prefPrefsList\">"; - - print "<tr><td width=\"40%\">".__("Sample value")."</td>"; - print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" name=\"example_value\" value=\"$value\"></td></tr>"; - - print "</table>"; - - print "<p><button dojoType=\"dijit.form.Button\" type=\"submit\">". - __("Set value")."</button>"; - - print "</form>"; - - print "</div>"; #pane - } -} -?> diff --git a/plugins/example_article/init.php b/plugins/example_article/init.php deleted file mode 100644 index 05f95a40a..000000000 --- a/plugins/example_article/init.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -class Example_Article extends Plugin { - - private $link; - private $host; - - function about() { - return array(1.0, - "Example plugin for HOOK_RENDER_ARTICLE", - "fox", - true); - } - - function init($host) { - $this->link = $host->get_link(); - $this->host = $host; - - $host->add_hook($host::HOOK_RENDER_ARTICLE, $this); - } - - function get_prefs_js() { - return file_get_contents(dirname(__FILE__) . "/init.js"); - } - - function hook_render_article($article) { - $article["content"] = "Content changed: " . $article["content"]; - - return $article; - } -} -?> diff --git a/plugins/example_feed/init.php b/plugins/example_feed/init.php deleted file mode 100644 index af14d3ff3..000000000 --- a/plugins/example_feed/init.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -class Example_Feed extends Plugin { - - // Demonstrates how to query data from the parsed feed object (SimplePie) - // don't enable unless debugging feed through f D hotkey or manually. - - private $link; - private $host; - - function about() { - return array(1.0, - "Example feed plugin", - "fox", - true); - } - - function init($host) { - $this->link = $host->get_link(); - $this->host = $host; - - $host->add_hook($host::HOOK_FEED_PARSED, $this); - } - - function hook_feed_parsed($feed) { - _debug("I'm a little feed short and stout, here's my title: " . $feed->get_title()); - _debug("... here's my link element: " . $feed->get_link()); - } -} -?> diff --git a/plugins/example_routing/init.php b/plugins/example_routing/init.php deleted file mode 100644 index 31c5b6f28..000000000 --- a/plugins/example_routing/init.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -class Example_Routing extends Plugin implements IHandler { - - // Demonstrates adding a custom handler and method: - // backend.php?op=test&method=example - // and masking a system builtin public method: - // public.php?op=getUnread - - // Plugin class must implelement IHandler interface and has - // a public method of same name as being registered. - // - // Any system method may be masked by plugins. You can mask - // entire handler by supplying "*" instead of a method name. - - private $link; - private $host; - - function about() { - return array(1.0, - "Example routing plugin", - "fox", - true); - } - - function init($host) { - $this->link = $host->get_link(); - $this->host = $host; - - $host->add_handler("test", "example", $this); - $host->add_handler("public", "getunread", $this); - } - - function getunread() { - print rand(0,100); # yeah right - } - - function example() { - print "example method called"; - } - - function csrf_ignore($method) { - return true; - } - - function before($method) { - return true; - } - - function after() { - return true; - } - -} -?> diff --git a/plugins/flattr/flattr.png b/plugins/flattr/flattr.png Binary files differdeleted file mode 100644 index 4933ffc21..000000000 --- a/plugins/flattr/flattr.png +++ /dev/null diff --git a/plugins/flattr/init.php b/plugins/flattr/init.php deleted file mode 100644 index d5e4ad025..000000000 --- a/plugins/flattr/init.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -class Flattr extends Plugin { - private $link; - private $host; - - function init($host) { - $this->link = $host->get_link(); - $this->host = $host; - - $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); - } - - function about() { - return array(1.1, - "Share articles on Flattr (if they exist in their catalogue)", - "F. Eitel, N. Honing"); - } - - function hook_article_button($line) { - - $rv = ""; - $article_link = $line['link']; - - if ($article_link) { - $encoded = urlencode($article_link); - $r = file_get_contents("https://api.flattr.com/rest/v2/things/lookup/?url=$encoded"); - $response = json_decode($r, true); - $image = "<img src=\"".theme_image($this->link, 'plugins/flattr/flattr.png')."\" - class='tagsPic' style=\"cursor : pointer\" - title='".__('Flattr this article.')."'>"; - // if Flattr has it in the catalogue, we display the button - if ($response and array_key_exists('link', $response)) { - $rv = "<a id='flattr' target='_blank' href='" . $response['link'] . "'> . $image . </a>"; - } else { - // We can't submit a thing to the catalogue without giving a Flattr user id (who would be the owner) - // see http://developers.flattr.net/auto-submit - //$rv = "<a id='flattr' href='https://flattr.com/submit/auto?url=" . $encoded . "'>" . $image . "</a>"; - $rv = ''; - // Another useful thing would be any rel=payment link (which would have the user id as well), - // but tt-rss is not checking that (yet), I believe. See http://developers.flattr.net/feed - } - } - return $rv; - } -} -?> diff --git a/plugins/googleplus/googleplus.js b/plugins/googleplus/googleplus.js deleted file mode 100644 index 027d9b40e..000000000 --- a/plugins/googleplus/googleplus.js +++ /dev/null @@ -1,29 +0,0 @@ - function shareArticleToGooglePlus(id) { - try { - var query = "?op=pluginhandler&plugin=googleplus&method=getInfo&id=" + param_escape(id); - - console.log(query); - - var d = new Date(); - var ts = d.getTime(); - - var w = window.open('backend.php?op=backend&method=loading', 'ttrss_tweet', - "status=0,toolbar=0,location=0,width=500,height=450,scrollbars=1,menubar=0"); - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - var ti = JSON.parse(transport.responseText); - - var share_url = "https://plus.google.com/share?url=" + param_escape(ti.link); - - w.location.href = share_url; - - } }); - - - } catch (e) { - exception_error("tweetArticle", e); - } - } - diff --git a/plugins/googleplus/googleplus.png b/plugins/googleplus/googleplus.png Binary files differdeleted file mode 100644 index ac46126d7..000000000 --- a/plugins/googleplus/googleplus.png +++ /dev/null diff --git a/plugins/googleplus/init.php b/plugins/googleplus/init.php deleted file mode 100644 index 3d6c60887..000000000 --- a/plugins/googleplus/init.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -class GooglePlus extends Plugin { - private $link; - private $host; - - function init($host) { - $this->link = $host->get_link(); - $this->host = $host; - - $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); - } - - function about() { - return array(1.0, - "Share article on Google+", - "homolibere"); - } - - function get_js() { - return file_get_contents(dirname(__FILE__) . "/googleplus.js"); - } - - function hook_article_button($line) { - $article_id = $line["id"]; - - $rv = "<img src=\"".theme_image($this->link, 'plugins/googleplus/googleplus.png')."\" - class='tagsPic' style=\"cursor : pointer\" - onclick=\"shareArticleToGooglePlus($article_id)\" - title='".__('Share on Google+')."'>"; - - return $rv; - } - - function getInfo() { - $id = db_escape_string($_REQUEST['id']); - - $result = db_query($this->link, "SELECT title, link - FROM ttrss_entries, ttrss_user_entries - WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']); - - if (db_num_rows($result) != 0) { - $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')), - 100, '...'); - $article_link = db_fetch_result($result, 0, 'link'); - } - - print json_encode(array("title" => $title, "link" => $article_link, - "id" => $id)); - } - - -} -?> diff --git a/plugins/googlereaderimport/init.js b/plugins/googlereaderimport/init.js new file mode 100644 index 000000000..043952c75 --- /dev/null +++ b/plugins/googlereaderimport/init.js @@ -0,0 +1,53 @@ +function starredImportComplete(iframe) { + try { + if (!iframe.contentDocument.body.innerHTML) return false; + + Element.show(iframe); + + notify(''); + + if (dijit.byId('starredImportDlg')) + dijit.byId('starredImportDlg').destroyRecursive(); + + var content = iframe.contentDocument.body.innerHTML; + + if (content) Element.hide(iframe); + + dialog = new dijit.Dialog({ + id: "starredImportDlg", + title: __("Google Reader Import"), + style: "width: 600px", + onCancel: function() { + Element.hide(iframe); + this.hide(); + }, + execute: function() { + Element.hide(iframe); + this.hide(); + }, + content: content}); + + dialog.show(); + + } catch (e) { + exception_error("starredImportComplete", e); + } +} + +function starredImport() { + + var starred_file = $("starred_file"); + + if (starred_file.value.length == 0) { + alert(__("Please choose a file first.")); + return false; + } else { + notify_progress("Importing, please wait...", true); + + Element.show("starred_upload_iframe"); + + return true; + } +} + + diff --git a/plugins/googlereaderimport/init.php b/plugins/googlereaderimport/init.php new file mode 100644 index 000000000..2e22161b9 --- /dev/null +++ b/plugins/googlereaderimport/init.php @@ -0,0 +1,383 @@ +<?php +class GoogleReaderImport extends Plugin { + private $host; + + function about() { + return array(1.0, + "Import starred/shared items from Google Reader takeout", + "fox", + false, + ""); + } + + function init($host) { + $this->host = $host; + + $host->add_command("greader-import", + "import data in Google Reader JSON format", + $this, ":", "FILE"); + + $host->add_hook($host::HOOK_PREFS_TAB, $this); + } + + function greader_import($args) { + $file = $args['greader_import']; + + if (!file_exists($file)) { + _debug("file not found: $file"); + return; + } + + _debug("please enter your username:"); + + $username = db_escape_string(trim(read_stdin())); + + _debug("looking up user: $username..."); + + $result = db_query("SELECT id FROM ttrss_users + WHERE login = '$username'"); + + if (db_num_rows($result) == 0) { + _debug("user not found."); + return; + } + + $owner_uid = db_fetch_result($result, 0, "id"); + + _debug("processing: $file (owner_uid: $owner_uid)"); + + $this->import($file, $owner_uid); + } + + function get_prefs_js() { + return file_get_contents(dirname(__FILE__) . "/init.js"); + } + + function import($file = false, $owner_uid = 0) { + + purge_orphans(); + + if (!$file) { + header("Content-Type: text/html"); + + $owner_uid = $_SESSION["uid"]; + + if ($_FILES['starred_file']['error'] != 0) { + print_error(T_sprintf("Upload failed with error code %d", + $_FILES['starred_file']['error'])); + return; + } + + $tmp_file = false; + + if (is_uploaded_file($_FILES['starred_file']['tmp_name'])) { + $tmp_file = tempnam(CACHE_DIR . '/upload', 'starred'); + + $result = move_uploaded_file($_FILES['starred_file']['tmp_name'], + $tmp_file); + + if (!$result) { + print_error(__("Unable to move uploaded file.")); + return; + } + } else { + print_error(__('Error: please upload OPML file.')); + return; + } + + if (is_file($tmp_file)) { + $doc = json_decode(file_get_contents($tmp_file), true); + unlink($tmp_file); + } else { + print_error(__('No file uploaded.')); + return; + } + } else { + $doc = json_decode(file_get_contents($file), true); + } + + if ($file) { + $sql_set_marked = strtolower(basename($file)) == 'starred.json' ? 'true' : 'false'; + _debug("will set articles as starred: $sql_set_marked"); + + } else { + $sql_set_marked = strtolower($_FILES['starred_file']['name']) == 'starred.json' ? 'true' : 'false'; + } + + if ($doc) { + if (isset($doc['items'])) { + $processed = 0; + + foreach ($doc['items'] as $item) { +// print_r($item); + + $guid = db_escape_string(mb_substr($item['id'], 0, 250)); + $title = db_escape_string($item['title']); + $updated = date('Y-m-d h:i:s', $item['updated']); + $link = ''; + $content = ''; + $author = db_escape_string($item['author']); + $tags = array(); + $orig_feed_data = array(); + + if (is_array($item['alternate'])) { + foreach ($item['alternate'] as $alt) { + if (isset($alt['type']) && $alt['type'] == 'text/html') { + $link = db_escape_string($alt['href']); + } + } + } + + if (is_array($item['summary'])) { + $content = db_escape_string( + $item['summary']['content'], false); + } + + if (is_array($item['content'])) { + $content = db_escape_string( + $item['content']['content'], false); + } + + if (is_array($item['categories'])) { + foreach ($item['categories'] as $cat) { + if (strstr($cat, "com.google/") === FALSE) { + array_push($tags, sanitize_tag($cat)); + } + } + } + + if (is_array($item['origin'])) { + if (strpos($item['origin']['streamId'], 'feed/') === 0) { + + $orig_feed_data['feed_url'] = db_escape_string( + mb_substr(preg_replace("/^feed\//", + "", $item['origin']['streamId']), 0, 200)); + + $orig_feed_data['title'] = db_escape_string( + mb_substr($item['origin']['title'], 0, 200)); + + $orig_feed_data['site_url'] = db_escape_string( + mb_substr($item['origin']['htmlUrl'], 0, 200)); + } + } + + $processed++; + + $imported += (int) $this->create_article($owner_uid, $guid, $title, + $link, $updated, $content, $author, $sql_set_marked, $tags, + $orig_feed_data); + + if ($file && $processed % 25 == 0) { + _debug("processed $processed articles..."); + } + } + + if ($file) { + _debug(sprintf("All done. %d of %d articles imported.", $imported, $processed)); + } else { + print "<p style='text-align : center'>" . T_sprintf("All done. %d out of %d articles imported.", $imported, $processed) . "</p>"; + } + + } else { + print_error(__('The document has incorrect format.')); + } + + } else { + print_error(__('Error while parsing document.')); + } + + if (!$file) { + print "<div align='center'>"; + print "<button dojoType=\"dijit.form.Button\" + onclick=\"dijit.byId('starredImportDlg').execute()\">". + __('Close this window')."</button>"; + print "</div>"; + } + } + + // expects ESCAPED data + private function create_article($owner_uid, $guid, $title, $link, $updated, $content, $author, $marked, $tags, $orig_feed_data) { + + if (!$guid) $guid = sha1($link); + + $create_archived_feeds = true; + + $guid = "$owner_uid,$guid"; + + $content_hash = sha1($content); + + if (filter_var(FILTER_VALIDATE_URL) === FALSE) return false; + + db_query("BEGIN"); + + $feed_id = 'NULL'; + + // let's check for archived feed entry + + $feed_inserted = false; + + // before dealing with archived feeds we must check ttrss_feeds to maintain id consistency + + if ($orig_feed_data['feed_url'] && $create_archived_feeds) { + $result = db_query( + "SELECT id FROM ttrss_feeds WHERE feed_url = '".$orig_feed_data['feed_url']."' + AND owner_uid = $owner_uid"); + + if (db_num_rows($result) != 0) { + $feed_id = db_fetch_result($result, 0, "id"); + } else { + // let's insert it + + if (!$orig_feed_data['title']) $orig_feed_data['title'] = '[Unknown]'; + + $result = db_query( + "INSERT INTO ttrss_feeds + (owner_uid,feed_url,site_url,title,cat_id,auth_login,auth_pass,update_method) + VALUES ($owner_uid, + '".$orig_feed_data['feed_url']."', + '".$orig_feed_data['site_url']."', + '".$orig_feed_data['title']."', + NULL, '', '', 0)"); + + $result = db_query( + "SELECT id FROM ttrss_feeds WHERE feed_url = '".$orig_feed_data['feed_url']."' + AND owner_uid = $owner_uid"); + + if (db_num_rows($result) != 0) { + $feed_id = db_fetch_result($result, 0, "id"); + $feed_inserted = true; + } + } + } + + if ($feed_id && $feed_id != 'NULL') { + // locate archived entry to file entries in, we don't want to file them in actual feeds because of purging + // maybe file marked in real feeds because eh + + $result = db_query("SELECT id FROM ttrss_archived_feeds WHERE + feed_url = '".$orig_feed_data['feed_url']."' AND owner_uid = $owner_uid"); + + if (db_num_rows($result) != 0) { + $orig_feed_id = db_fetch_result($result, 0, "id"); + } else { + db_query("INSERT INTO ttrss_archived_feeds + (id, owner_uid, title, feed_url, site_url) + SELECT id, owner_uid, title, feed_url, site_url from ttrss_feeds + WHERE id = '$feed_id'"); + + $result = db_query("SELECT id FROM ttrss_archived_feeds WHERE + feed_url = '".$orig_feed_data['feed_url']."' AND owner_uid = $owner_uid"); + + if (db_num_rows($result) != 0) { + $orig_feed_id = db_fetch_result($result, 0, "id"); + } + } + } + + // delete temporarily inserted feed + if ($feed_id && $feed_inserted) { + db_query("DELETE FROM ttrss_feeds WHERE id = $feed_id"); + } + + if (!$orig_feed_id) $orig_feed_id = 'NULL'; + + $result = db_query("SELECT id FROM ttrss_entries, ttrss_user_entries WHERE + guid = '$guid' AND ref_id = id AND owner_uid = '$owner_uid' LIMIT 1"); + + if (db_num_rows($result) == 0) { + $result = db_query("INSERT INTO ttrss_entries + (title, guid, link, updated, content, content_hash, date_entered, date_updated, author) + VALUES + ('$title', '$guid', '$link', '$updated', '$content', '$content_hash', NOW(), NOW(), '$author')"); + + $result = db_query("SELECT id FROM ttrss_entries WHERE guid = '$guid'"); + + if (db_num_rows($result) != 0) { + $ref_id = db_fetch_result($result, 0, "id"); + + db_query("INSERT INTO ttrss_user_entries + (ref_id, uuid, feed_id, orig_feed_id, owner_uid, marked, tag_cache, label_cache, + last_read, note, unread, last_marked) + VALUES + ('$ref_id', '', NULL, $orig_feed_id, $owner_uid, $marked, '', '', NOW(), '', false, NOW())"); + + $result = db_query("SELECT int_id FROM ttrss_user_entries, ttrss_entries + WHERE owner_uid = $owner_uid AND ref_id = id AND ref_id = $ref_id"); + + if (db_num_rows($result) != 0 && is_array($tags)) { + + $entry_int_id = db_fetch_result($result, 0, "int_id"); + $tags_to_cache = array(); + + foreach ($tags as $tag) { + + $tag = db_escape_string(sanitize_tag($tag)); + + if (!tag_is_valid($tag)) continue; + + $result = db_query("SELECT id FROM ttrss_tags + WHERE tag_name = '$tag' AND post_int_id = '$entry_int_id' AND + owner_uid = '$owner_uid' LIMIT 1"); + + if ($result && db_num_rows($result) == 0) { + db_query("INSERT INTO ttrss_tags + (owner_uid,tag_name,post_int_id) + VALUES ('$owner_uid','$tag', '$entry_int_id')"); + } + + array_push($tags_to_cache, $tag); + } + + /* update the cache */ + + $tags_to_cache = array_unique($tags_to_cache); + $tags_str = db_escape_string(join(",", $tags_to_cache)); + + db_query("UPDATE ttrss_user_entries + SET tag_cache = '$tags_str' WHERE ref_id = '$ref_id' + AND owner_uid = $owner_uid"); + } + + $rc = true; + } + } + + db_query("COMMIT"); + + return $rc; + } + + function hook_prefs_tab($args) { + if ($args != "prefFeeds") return; + + print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__("Import starred or shared items from Google Reader")."\">"; + + print_notice("Your imported articles will appear in Starred (in file is named starred.json) and Archived feeds."); + + print "<p>".__("Paste your starred.json or shared.json into the form below."). "</p>"; + + print "<iframe id=\"starred_upload_iframe\" + name=\"starred_upload_iframe\" onload=\"starredImportComplete(this)\" + style=\"width: 400px; height: 100px; display: none;\"></iframe>"; + + print "<form name=\"starred_form\" style='display : block' target=\"starred_upload_iframe\" + enctype=\"multipart/form-data\" method=\"POST\" + action=\"backend.php\"> + <input id=\"starred_file\" name=\"starred_file\" type=\"file\"> + <input type=\"hidden\" name=\"op\" value=\"pluginhandler\"> + <input type=\"hidden\" name=\"method\" value=\"import\"> + <input type=\"hidden\" name=\"plugin\" value=\"googlereaderimport\"> + <button dojoType=\"dijit.form.Button\" onclick=\"return starredImport();\" type=\"submit\">" . + __('Import my Starred items') . "</button>"; + + print "</form>"; + + print "</div>"; #pane + } + + function api_version() { + return 2; + } + +} +?> diff --git a/plugins/googlereaderkeys/init.php b/plugins/googlereaderkeys/init.php index 97133d305..c8e7d7a38 100644 --- a/plugins/googlereaderkeys/init.php +++ b/plugins/googlereaderkeys/init.php @@ -1,7 +1,5 @@ <?php class GoogleReaderKeys extends Plugin { - - private $link; private $host; function about() { @@ -11,7 +9,6 @@ class GoogleReaderKeys extends Plugin { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_HOTKEY_MAP, $this); @@ -21,16 +18,21 @@ class GoogleReaderKeys extends Plugin { $hotkeys["j"] = "next_article_noscroll"; $hotkeys["k"] = "prev_article_noscroll"; - $hotkeys["N"] = "next_feed"; - $hotkeys["P"] = "prev_feed"; + $hotkeys["*n"] = "next_feed"; + $hotkeys["*p"] = "prev_feed"; $hotkeys["v"] = "open_in_new_window"; $hotkeys["r"] = "feed_refresh"; + $hotkeys["m"] = "toggle_unread"; $hotkeys["(32)|space"] = "next_article"; $hotkeys["(38)|up"] = "article_scroll_up"; $hotkeys["(40)|down"] = "article_scroll_down"; return $hotkeys; + } + function api_version() { + return 2; } + } ?> diff --git a/plugins/identica/identica.js b/plugins/identica/identica.js deleted file mode 100644 index d31fc55f4..000000000 --- a/plugins/identica/identica.js +++ /dev/null @@ -1,31 +0,0 @@ - function shareArticleToIdentica(id) { - try { - var query = "?op=pluginhandler&plugin=identica&method=getInfo&id=" + param_escape(id); - - console.log(query); - - var d = new Date(); - var ts = d.getTime(); - - var w = window.open('backend.php?op=backend&method=loading', 'ttrss_tweet', - "status=0,toolbar=0,location=0,width=600,height=500,scrollbars=1,menubar=0"); - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - var ti = JSON.parse(transport.responseText); - - var share_url = "http://identi.ca/index.php?action=bookmarkpopup&_=" + ts + - "&title=" + param_escape(ti.title) + - "&url=" + param_escape(ti.link); - - w.location.href = share_url; - - } }); - - - } catch (e) { - exception_error("shareArticleIdentica", e); - } - } - diff --git a/plugins/identica/identica.png b/plugins/identica/identica.png Binary files differdeleted file mode 100644 index ee3cb61ea..000000000 --- a/plugins/identica/identica.png +++ /dev/null diff --git a/plugins/identica/init.php b/plugins/identica/init.php deleted file mode 100644 index c260334af..000000000 --- a/plugins/identica/init.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -class Identica extends Plugin { - private $link; - private $host; - - function init($host) { - $this->link = $host->get_link(); - $this->host = $host; - - $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); - } - - function about() { - return array(1.0, - "Share articles on Identi.ca", - "fox"); - } - - function get_js() { - return file_get_contents(dirname(__FILE__) . "/identica.js"); - } - - function hook_article_button($line) { - $article_id = $line["id"]; - - $rv = "<img src=\"".theme_image($this->link, 'plugins/identica/identica.png')."\" - class='tagsPic' style=\"cursor : pointer\" - onclick=\"shareArticleToIdentica($article_id)\" - title='".__('Share on identi.ca')."'>"; - - return $rv; - } - - function getInfo() { - $id = db_escape_string($_REQUEST['id']); - - $result = db_query($this->link, "SELECT title, link - FROM ttrss_entries, ttrss_user_entries - WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']); - - if (db_num_rows($result) != 0) { - $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')), - 100, '...'); - $article_link = db_fetch_result($result, 0, 'link'); - } - - print json_encode(array("title" => $title, "link" => $article_link, - "id" => $id)); - } - - -} -?> diff --git a/plugins/import_export/import_export.js b/plugins/import_export/import_export.js index b3b760f15..780f6bfc7 100644 --- a/plugins/import_export/import_export.js +++ b/plugins/import_export/import_export.js @@ -17,7 +17,7 @@ function exportData() { notify_progress("Loading, please wait..."); new Ajax.Request("backend.php", { - parameters: "?op=pluginhandler&plugin=import_export&method=exportrun&offset=" + exported, + parameters: "op=pluginhandler&plugin=import_export&method=exportrun&offset=" + exported, onComplete: function(transport) { try { var rv = JSON.parse(transport.responseText); @@ -37,7 +37,7 @@ function exportData() { } else { $("export_status_message").innerHTML = - __("Finished, exported %d articles. You can download the data <a class='visibleLink' href='%u'>here</a>.") + ngettext("Finished, exported %d article. You can download the data <a class='visibleLink' href='%u'>here</a>.", "Finished, exported %d articles. You can download the data <a class='visibleLink' href='%u'>here</a>.", exported) .replace("%d", exported) .replace("%u", "backend.php?op=pluginhandler&plugin=import_export&subop=exportget"); diff --git a/plugins/import_export/init.php b/plugins/import_export/init.php index de21dbf32..d4bdec826 100644 --- a/plugins/import_export/init.php +++ b/plugins/import_export/init.php @@ -1,15 +1,12 @@ <?php class Import_Export extends Plugin implements IHandler { - - private $link; private $host; function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_PREFS_TAB, $this); - $host->add_command("xml-import", "USER FILE: import articles from XML", $this); + $host->add_command("xml-import", "import articles from XML", $this, ":", "FILE"); } function about() { @@ -19,24 +16,21 @@ class Import_Export extends Plugin implements IHandler { } function xml_import($args) { - array_shift($args); - $username = $args[count($args) - 2]; - $filename = $args[count($args) - 1]; - - if (!$username) { - print "error: please specify username.\n"; - return; - } + $filename = $args['xml_import']; if (!is_file($filename)) { print "error: input filename ($filename) doesn't exist.\n"; return; } + _debug("please enter your username:"); + + $username = db_escape_string(trim(read_stdin())); + _debug("importing $filename for user $username...\n"); - $result = db_query($this->link, "SELECT id FROM ttrss_users WHERE login = '$username'"); + $result = db_query("SELECT id FROM ttrss_users WHERE login = '$username'"); if (db_num_rows($result) == 0) { print "error: could not find user $username.\n"; @@ -45,7 +39,7 @@ class Import_Export extends Plugin implements IHandler { $owner_uid = db_fetch_result($result, 0, "id"); - $this->perform_data_import($this->link, $filename, $owner_uid); + $this->perform_data_import($filename, $owner_uid); } function save() { @@ -63,9 +57,9 @@ class Import_Export extends Plugin implements IHandler { print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Import and export')."\">"; - print "<h3>" . __("Article archive") . "</h3>"; + print_notice(__("You can export and import your Starred and Archived articles for safekeeping or when migrating between tt-rss instances of same version.")); - print "<p>" . __("You can export and import your Starred and Archived articles for safekeeping or when migrating between tt-rss instances.") . "</p>"; + print "<p>"; print "<button dojoType=\"dijit.form.Button\" onclick=\"return exportData()\">". __('Export my data')."</button> "; @@ -86,6 +80,9 @@ class Import_Export extends Plugin implements IHandler { <button dojoType=\"dijit.form.Button\" onclick=\"return importData();\" type=\"submit\">" . __('Import') . "</button>"; + print "</form>"; + + print "</p>"; print "</div>"; # pane } @@ -127,7 +124,7 @@ class Import_Export extends Plugin implements IHandler { $limit = 250; if ($offset < 10000 && is_writable(CACHE_DIR . "/export")) { - $result = db_query($this->link, "SELECT + $result = db_query("SELECT ttrss_entries.guid, ttrss_entries.title, content, @@ -165,6 +162,7 @@ class Import_Export extends Plugin implements IHandler { fputs($fp, "<article>"); foreach ($line as $k => $v) { + $v = str_replace("]]>", "]]]]><![CDATA[>", $v); fputs($fp, "<$k><![CDATA[$v]]></$k>"); } @@ -185,7 +183,7 @@ class Import_Export extends Plugin implements IHandler { print json_encode(array("exported" => $exported)); } - function perform_data_import($link, $filename, $owner_uid) { + function perform_data_import($filename, $owner_uid) { $num_imported = 0; $num_processed = 0; @@ -249,16 +247,16 @@ class Import_Export extends Plugin implements IHandler { ++$num_processed; - //db_query($link, "BEGIN"); + //db_query("BEGIN"); //print 'GUID:' . $article['guid'] . "\n"; - $result = db_query($link, "SELECT id FROM ttrss_entries + $result = db_query("SELECT id FROM ttrss_entries WHERE guid = '".$article['guid']."'"); if (db_num_rows($result) == 0) { - $result = db_query($link, + $result = db_query( "INSERT INTO ttrss_entries (title, guid, @@ -286,7 +284,7 @@ class Import_Export extends Plugin implements IHandler { '0', '')"); - $result = db_query($link, "SELECT id FROM ttrss_entries + $result = db_query("SELECT id FROM ttrss_entries WHERE guid = '".$article['guid']."'"); if (db_num_rows($result) != 0) { @@ -307,7 +305,7 @@ class Import_Export extends Plugin implements IHandler { $feed = 'NULL'; if ($feed_url && $feed_title) { - $result = db_query($link, "SELECT id FROM ttrss_feeds + $result = db_query("SELECT id FROM ttrss_feeds WHERE feed_url = '$feed_url' AND owner_uid = '$owner_uid'"); if (db_num_rows($result) != 0) { @@ -315,10 +313,10 @@ class Import_Export extends Plugin implements IHandler { } else { // try autocreating feed in Uncategorized... - $result = db_query($link, "INSERT INTO ttrss_feeds (owner_uid, + $result = db_query("INSERT INTO ttrss_feeds (owner_uid, feed_url, title) VALUES ($owner_uid, '$feed_url', '$feed_title')"); - $result = db_query($link, "SELECT id FROM ttrss_feeds + $result = db_query("SELECT id FROM ttrss_feeds WHERE feed_url = '$feed_url' AND owner_uid = '$owner_uid'"); if (db_num_rows($result) != 0) { @@ -336,7 +334,7 @@ class Import_Export extends Plugin implements IHandler { //print "$ref_id / $feed / " . $article['title'] . "\n"; - $result = db_query($link, "SELECT int_id FROM ttrss_user_entries + $result = db_query("SELECT int_id FROM ttrss_user_entries WHERE ref_id = '$ref_id' AND owner_uid = '$owner_uid' AND $feed_qpart"); if (db_num_rows($result) == 0) { @@ -353,7 +351,7 @@ class Import_Export extends Plugin implements IHandler { ++$num_imported; - $result = db_query($link, + $result = db_query( "INSERT INTO ttrss_user_entries (ref_id, owner_uid, feed_id, unread, last_read, marked, published, score, tag_cache, label_cache, uuid, note) @@ -366,15 +364,15 @@ class Import_Export extends Plugin implements IHandler { if (is_array($label_cache) && $label_cache["no-labels"] != 1) { foreach ($label_cache as $label) { - label_create($link, $label[1], + label_create($label[1], $label[2], $label[3], $owner_uid); - label_add_article($link, $ref_id, $label[1], $owner_uid); + label_add_article($ref_id, $label[1], $owner_uid); } } - //db_query($link, "COMMIT"); + //db_query("COMMIT"); } } } @@ -382,8 +380,10 @@ class Import_Export extends Plugin implements IHandler { } print "<p>" . - T_sprintf("Finished: %d articles processed, %d imported, %d feeds created.", - $num_processed, $num_imported, $num_feeds_created) . + __("Finished: "). + vsprintf(ngettext("%d article processed, ", "%d articles processed, ", $num_processed), $num_processed). + vsprintf(ngettext("%d imported, ", "%d imported, ", $num_imported), $num_imported). + vsprintf(ngettext("%d feed created.", "%d feeds created.", $num_feeds_created), $num_feeds_created). "</p>"; } else { @@ -416,14 +416,35 @@ class Import_Export extends Plugin implements IHandler { print "<div style='text-align : center'>"; - if (is_file($_FILES['export_file']['tmp_name'])) { + if ($_FILES['export_file']['error'] != 0) { + print_error(T_sprintf("Upload failed with error code %d", + $_FILES['export_file']['error'])); + return; + } + + $tmp_file = false; + + if (is_uploaded_file($_FILES['export_file']['tmp_name'])) { + $tmp_file = tempnam(CACHE_DIR . '/upload', 'export'); - $this->perform_data_import($this->link, $_FILES['export_file']['tmp_name'], $_SESSION['uid']); + $result = move_uploaded_file($_FILES['export_file']['tmp_name'], + $tmp_file); + if (!$result) { + print_error(__("Unable to move uploaded file.")); + return; + } } else { - print "<p>" . T_sprintf("Could not upload file. You might need to adjust upload_max_filesize - in PHP.ini (current value = %s)", ini_get("upload_max_filesize")) . " or use CLI import tool.</p>"; + print_error(__('Error: please upload OPML file.')); + return; + } + if (is_file($tmp_file)) { + $this->perform_data_import($tmp_file, $_SESSION['uid']); + unlink($tmp_file); + } else { + print_error(__('No file uploaded.')); + return; } print "<button dojoType=\"dijit.form.Button\" @@ -434,6 +455,9 @@ class Import_Export extends Plugin implements IHandler { } + function api_version() { + return 2; + } } ?> diff --git a/plugins/example_article/init.js b/plugins/index.html index e69de29bb..e69de29bb 100644 --- a/plugins/example_article/init.js +++ b/plugins/index.html diff --git a/plugins/instances/init.php b/plugins/instances/init.php index 6c0f89e1c..aac28196f 100644 --- a/plugins/instances/init.php +++ b/plugins/instances/init.php @@ -1,7 +1,5 @@ <?php class Instances extends Plugin implements IHandler { - - private $link; private $host; private $status_codes = array( @@ -18,7 +16,6 @@ class Instances extends Plugin implements IHandler { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_PREFS_TABS, $this); @@ -30,7 +27,7 @@ class Instances extends Plugin implements IHandler { function hook_update_task($args) { _debug("Get linked feeds..."); - $this->get_linked_feeds($this->link); + $this->get_linked_feeds(); } // Status codes: @@ -40,7 +37,7 @@ class Instances extends Plugin implements IHandler { // 2 - did not receive valid data // >10 - server error, code + 10 (e.g. 16 means server error 6) - function get_linked_feeds($link, $instance_id = false) { + function get_linked_feeds($instance_id = false) { if ($instance_id) $instance_qpart = "id = '$instance_id' AND "; else @@ -52,7 +49,7 @@ class Instances extends Plugin implements IHandler { $date_qpart = "last_connected < DATE_SUB(NOW(), INTERVAL 6 HOUR)"; } - $result = db_query($link, "SELECT id, access_key, access_url FROM ttrss_linked_instances + $result = db_query("SELECT id, access_key, access_url FROM ttrss_linked_instances WHERE $instance_qpart $date_qpart ORDER BY last_connected"); while ($line = db_fetch_assoc($result)) { @@ -80,7 +77,7 @@ class Instances extends Plugin implements IHandler { // access denied if ($status == 16) { - db_query($link, "DELETE FROM ttrss_linked_feeds + db_query("DELETE FROM ttrss_linked_feeds WHERE instance_id = '$id'"); } } else { @@ -88,7 +85,7 @@ class Instances extends Plugin implements IHandler { if (count($feeds['feeds']) > 0) { - db_query($link, "DELETE FROM ttrss_linked_feeds + db_query("DELETE FROM ttrss_linked_feeds WHERE instance_id = '$id'"); foreach ($feeds['feeds'] as $feed) { @@ -97,7 +94,7 @@ class Instances extends Plugin implements IHandler { $subscribers = db_escape_string($feed['subscribers']); $site_url = db_escape_string($feed['site_url']); - db_query($link, "INSERT INTO ttrss_linked_feeds + db_query("INSERT INTO ttrss_linked_feeds (feed_url, site_url, title, subscribers, instance_id, created, updated) VALUES ('$feed_url', '$site_url', '$title', '$subscribers', '$id', NOW(), NOW())"); @@ -122,7 +119,7 @@ class Instances extends Plugin implements IHandler { _debug("Status: $status"); - db_query($link, "UPDATE ttrss_linked_instances SET + db_query("UPDATE ttrss_linked_instances SET last_status_out = '$status', last_connected = NOW() WHERE id = '$id'"); } @@ -130,7 +127,7 @@ class Instances extends Plugin implements IHandler { function get_feeds() { - $this->get_linked_feeds($this->link, false); + $this->get_linked_feeds(false); } function get_prefs_js() { @@ -169,7 +166,7 @@ class Instances extends Plugin implements IHandler { function remove() { $ids = db_escape_string($_REQUEST['ids']); - db_query($this->link, "DELETE FROM ttrss_linked_instances WHERE + db_query("DELETE FROM ttrss_linked_instances WHERE id IN ($ids)"); } @@ -178,26 +175,26 @@ class Instances extends Plugin implements IHandler { $access_url = db_escape_string($_REQUEST["access_url"]); $access_key = db_escape_string($_REQUEST["access_key"]); - db_query($this->link, "BEGIN"); + db_query("BEGIN"); - $result = db_query($this->link, "SELECT id FROM ttrss_linked_instances + $result = db_query("SELECT id FROM ttrss_linked_instances WHERE access_url = '$access_url'"); if (db_num_rows($result) == 0) { - db_query($this->link, "INSERT INTO ttrss_linked_instances + db_query("INSERT INTO ttrss_linked_instances (access_url, access_key, last_connected, last_status_in, last_status_out) VALUES ('$access_url', '$access_key', '1970-01-01', -1, -1)"); } - db_query($this->link, "COMMIT"); + db_query("COMMIT"); } function edit() { $id = db_escape_string($_REQUEST["id"]); - $result = db_query($this->link, "SELECT * FROM ttrss_linked_instances WHERE + $result = db_query("SELECT * FROM ttrss_linked_instances WHERE id = '$id'"); print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"id\" value=\"$id\">"; @@ -257,7 +254,7 @@ class Instances extends Plugin implements IHandler { $access_url = db_escape_string($_REQUEST["access_url"]); $access_key = db_escape_string($_REQUEST["access_key"]); - db_query($this->link, "UPDATE ttrss_linked_instances SET + db_query("UPDATE ttrss_linked_instances SET access_key = '$access_key', access_url = '$access_url', last_connected = '1970-01-01' WHERE id = '$id'"); @@ -298,7 +295,7 @@ class Instances extends Plugin implements IHandler { print "</div>"; #toolbar - $result = db_query($this->link, "SELECT *, + $result = db_query("SELECT *, (SELECT COUNT(*) FROM ttrss_linked_feeds WHERE instance_id = ttrss_linked_instances.id) AS num_feeds FROM ttrss_linked_instances @@ -327,7 +324,7 @@ class Instances extends Plugin implements IHandler { $id = $line['id']; $this_row_id = "id=\"LIRR-$id\""; - $line["last_connected"] = make_local_datetime($this->link, $line["last_connected"], false); + $line["last_connected"] = make_local_datetime($line["last_connected"], false); print "<tr class=\"$class\" $this_row_id>"; @@ -354,8 +351,7 @@ class Instances extends Plugin implements IHandler { print "</div>"; #pane - global $pluginhost; - $pluginhost->run_hooks($pluginhost::HOOK_PREFS_TAB, + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, "hook_prefs_tab", "prefInstances"); print "</div>"; #container @@ -367,14 +363,14 @@ class Instances extends Plugin implements IHandler { $access_key = db_escape_string($_POST["key"]); // TODO: rate limit checking using last_connected - $result = db_query($this->link, "SELECT id FROM ttrss_linked_instances + $result = db_query("SELECT id FROM ttrss_linked_instances WHERE access_key = '$access_key'"); if (db_num_rows($result) == 1) { $instance_id = db_fetch_result($result, 0, "id"); - $result = db_query($this->link, "SELECT feed_url, site_url, title, subscribers + $result = db_query("SELECT feed_url, site_url, title, subscribers FROM ttrss_feedbrowser_cache ORDER BY subscribers DESC LIMIT 100"); $feeds = array(); @@ -383,7 +379,7 @@ class Instances extends Plugin implements IHandler { array_push($feeds, $line); } - db_query($this->link, "UPDATE ttrss_linked_instances SET + db_query("UPDATE ttrss_linked_instances SET last_status_in = 1 WHERE id = '$instance_id'"); print json_encode(array("feeds" => $feeds)); @@ -392,6 +388,65 @@ class Instances extends Plugin implements IHandler { } } + function addInstance() { + print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pref-instances\">"; + print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"add\">"; + + print "<div class=\"dlgSec\">".__("Instance")."</div>"; + + print "<div class=\"dlgSecCont\">"; + + /* URL */ + + print __("URL:") . " "; + + print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" + placeHolder=\"".__("Instance URL")."\" + regExp='^(http|https)://.*' + style=\"font-size : 16px; width: 20em\" name=\"access_url\">"; + + print "<hr/>"; + + $access_key = sha1(uniqid(rand(), true)); + + /* Access key */ + + print __("Access key:") . " "; + + print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" + placeHolder=\"".__("Access key")."\" regExp='\w{40}' + style=\"width: 20em\" name=\"access_key\" id=\"instance_add_key\" + value=\"$access_key\">"; + + print "<p class='insensitive'>" . __("Use one access key for both linked instances."); + + print "</div>"; + + print "<div class=\"dlgButtons\"> + <div style='float : left'> + <button dojoType=\"dijit.form.Button\" + onclick=\"return dijit.byId('instanceAddDlg').regenKey()\">". + __('Generate new key')."</button> + </div> + <button dojoType=\"dijit.form.Button\" + onclick=\"return dijit.byId('instanceAddDlg').execute()\">". + __('Create link')."</button> + <button dojoType=\"dijit.form.Button\" + onclick=\"return dijit.byId('instanceAddDlg').hide()\"\">". + __('Cancel')."</button></div>"; + + return; + } + + function genHash() { + $hash = sha1(uniqid(rand(), true)); + + print json_encode(array("hash" => $hash)); + } + + function api_version() { + return 2; + } } ?> diff --git a/plugins/instances/instances.js b/plugins/instances/instances.js index 83213896d..f699acf72 100644 --- a/plugins/instances/instances.js +++ b/plugins/instances/instances.js @@ -1,6 +1,6 @@ function addInstance() { try { - var query = "backend.php?op=dlg&method=addInstance"; + var query = "backend.php?op=pluginhandler&plugin=instances&method=addInstance"; if (dijit.byId("instanceAddDlg")) dijit.byId("instanceAddDlg").destroyRecursive(); @@ -11,7 +11,7 @@ function addInstance() { style: "width: 600px", regenKey: function() { new Ajax.Request("backend.php", { - parameters: "?op=rpc&method=genHash", + parameters: "op=pluginhandler&plugin=instances&method=genHash", onComplete: function(transport) { var reply = JSON.parse(transport.responseText); if (reply) @@ -47,7 +47,7 @@ function addInstance() { function updateInstanceList(sort_key) { new Ajax.Request("backend.php", { - parameters: "?op=pref-instances&sort=" + param_escape(sort_key), + parameters: "op=pluginhandler&plugin=instances&sort=" + param_escape(sort_key), onComplete: function(transport) { dijit.byId('instanceConfigTab').attr('content', transport.responseText); selectTab("instanceConfig", true); @@ -62,7 +62,7 @@ function editInstance(id, event) { selectTableRows('prefInstanceList', 'none'); selectTableRowById('LIRR-'+id, 'LICHK-'+id, true); - var query = "backend.php?op=pref-instances&method=edit&id=" + + var query = "backend.php?op=pluginhandler&plugin=instances&method=edit&id=" + param_escape(id); if (dijit.byId("instanceEditDlg")) @@ -74,7 +74,7 @@ function editInstance(id, event) { style: "width: 600px", regenKey: function() { new Ajax.Request("backend.php", { - parameters: "?op=rpc&method=genHash", + parameters: "op=pluginhandler&plugin=instances&method=genHash", onComplete: function(transport) { var reply = JSON.parse(transport.responseText); if (reply) @@ -124,7 +124,7 @@ function removeSelectedInstances() { if (ok) { notify_progress("Removing selected instances..."); - var query = "?op=pref-instances&method=remove&ids="+ + var query = "op=pluginhandler&plugin=instances&method=remove&ids="+ param_escape(sel_rows.toString()); new Ajax.Request("backend.php", { diff --git a/plugins/mail/init.php b/plugins/mail/init.php index 2e972cf61..80bc7d417 100644 --- a/plugins/mail/init.php +++ b/plugins/mail/init.php @@ -1,7 +1,6 @@ <?php class Mail extends Plugin { - private $link; private $host; function about() { @@ -11,7 +10,6 @@ class Mail extends Plugin { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); @@ -22,7 +20,7 @@ class Mail extends Plugin { } function hook_article_button($line) { - return "<img src=\"".theme_image($link, 'plugins/mail/mail.png')."\" + return "<img src=\"plugins/mail/mail.png\" class='tagsPic' style=\"cursor : pointer\" onclick=\"emailArticle(".$line["id"].")\" alt='Zoom' title='".__('Forward by email')."'>"; @@ -32,16 +30,11 @@ class Mail extends Plugin { $param = db_escape_string($_REQUEST['param']); - $secretkey = sha1(uniqid(rand(), true)); - - $_SESSION['email_secretkey'] = $secretkey; - - print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"secretkey\" value=\"$secretkey\">"; print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pluginhandler\">"; print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"plugin\" value=\"mail\">"; print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"sendEmail\">"; - $result = db_query($this->link, "SELECT email, full_name FROM ttrss_users WHERE + $result = db_query("SELECT email, full_name FROM ttrss_users WHERE id = " . $_SESSION["uid"]); $user_email = htmlspecialchars(db_fetch_result($result, 0, "email")); @@ -49,8 +42,8 @@ class Mail extends Plugin { if (!$user_name) $user_name = $_SESSION['name']; - $_SESSION['email_replyto'] = $user_email; - $_SESSION['email_fromname'] = $user_name; + print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"from_email\" value=\"$user_email\">"; + print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"from_name\" value=\"$user_name\">"; require_once "lib/MiniTemplator.class.php"; @@ -59,12 +52,11 @@ class Mail extends Plugin { $tpl->readTemplateFromFile("templates/email_article_template.txt"); - $tpl->setVariable('USER_NAME', $_SESSION["name"]); - $tpl->setVariable('USER_EMAIL', $user_email); - $tpl->setVariable('TTRSS_HOST', $_SERVER["HTTP_HOST"]); + $tpl->setVariable('USER_NAME', $_SESSION["name"], true); + $tpl->setVariable('USER_EMAIL', $user_email, true); + $tpl->setVariable('TTRSS_HOST', $_SERVER["HTTP_HOST"], true); - - $result = db_query($this->link, "SELECT link, content, title + $result = db_query("SELECT link, content, title FROM ttrss_user_entries, ttrss_entries WHERE id = ref_id AND id IN ($param) AND owner_uid = " . $_SESSION["uid"]); @@ -136,58 +128,27 @@ class Mail extends Plugin { } function sendEmail() { - $secretkey = $_REQUEST['secretkey']; - - require_once 'lib/phpmailer/class.phpmailer.php'; + require_once 'classes/ttrssmailer.php'; $reply = array(); - if ($_SESSION['email_secretkey'] && - $secretkey == $_SESSION['email_secretkey']) { - - $_SESSION['email_secretkey'] = ''; - - $destination = $_REQUEST['destination']; - $subject = $_REQUEST['subject']; - $content = $_REQUEST['content']; - - $replyto = strip_tags($_SESSION['email_replyto']); - $fromname = strip_tags($_SESSION['email_fromname']); - - $mail = new PHPMailer(); + $mail = new ttrssMailer(); - $mail->PluginDir = "lib/phpmailer/"; - $mail->SetLanguage("en", "lib/phpmailer/language/"); + $mail->From = strip_tags($_REQUEST['from_email']); + $mail->FromName = strip_tags($_REQUEST['from_name']); + $mail->AddAddress($_REQUEST['destination']); - $mail->CharSet = "UTF-8"; + $mail->IsHTML(false); + $mail->Subject = $_REQUEST['subject']; + $mail->Body = $_REQUEST['content']; - $mail->From = $replyto; - $mail->FromName = $fromname; - $mail->AddAddress($destination); - - if (SMTP_HOST) { - $mail->Host = SMTP_HOST; - $mail->Mailer = "smtp"; - $mail->SMTPAuth = SMTP_LOGIN != ''; - $mail->Username = SMTP_LOGIN; - $mail->Password = SMTP_PASSWORD; - } - - $mail->IsHTML(false); - $mail->Subject = $subject; - $mail->Body = $content; - - $rc = $mail->Send(); - - if (!$rc) { - $reply['error'] = $mail->ErrorInfo; - } else { - save_email_address($this->link, db_escape_string($destination)); - $reply['message'] = "UPDATE_COUNTERS"; - } + $rc = $mail->Send(); + if (!$rc) { + $reply['error'] = $mail->ErrorInfo; } else { - $reply['error'] = "Not authorized."; + save_email_address(db_escape_string($destination)); + $reply['message'] = "UPDATE_COUNTERS"; } print json_encode($reply); @@ -207,6 +168,9 @@ class Mail extends Plugin { print "</ul>"; } + function api_version() { + return 2; + } } ?> diff --git a/plugins/mail/mail.js b/plugins/mail/mail.js index 39f753cc0..6166f01c1 100644 --- a/plugins/mail/mail.js +++ b/plugins/mail/mail.js @@ -26,6 +26,7 @@ function emailArticle(id) { new Ajax.Request("backend.php", { parameters: dojo.objectToQuery(this.attr('value')), onComplete: function(transport) { + console.log(transport.responseText); var reply = JSON.parse(transport.responseText); diff --git a/plugins/mailto/init.js b/plugins/mailto/init.js new file mode 100644 index 000000000..8f7656a07 --- /dev/null +++ b/plugins/mailto/init.js @@ -0,0 +1,32 @@ +function mailtoArticle(id) { + try { + if (!id) { + var ids = getSelectedArticleIds2(); + + if (ids.length == 0) { + alert(__("No articles are selected.")); + return; + } + + id = ids.toString(); + } + + if (dijit.byId("emailArticleDlg")) + dijit.byId("emailArticleDlg").destroyRecursive(); + + var query = "backend.php?op=pluginhandler&plugin=mailto&method=emailArticle¶m=" + param_escape(id); + + dialog = new dijit.Dialog({ + id: "emailArticleDlg", + title: __("Forward article by email"), + style: "width: 600px", + href: query}); + + dialog.show(); + + } catch (e) { + exception_error("emailArticle", e); + } +} + + diff --git a/plugins/mailto/init.php b/plugins/mailto/init.php new file mode 100644 index 000000000..aa6d173f8 --- /dev/null +++ b/plugins/mailto/init.php @@ -0,0 +1,94 @@ +<?php +class MailTo extends Plugin { + private $host; + + function about() { + return array(1.0, + "Share article via email (using mailto: links, invoking your mail client)", + "fox"); + } + + function init($host) { + $this->host = $host; + + $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); + } + + function get_js() { + return file_get_contents(dirname(__FILE__) . "/init.js"); + } + + function hook_article_button($line) { + return "<img src=\"plugins/mailto/mail.png\" + class='tagsPic' style=\"cursor : pointer\" + onclick=\"mailtoArticle(".$line["id"].")\" + alt='Zoom' title='".__('Forward by email')."'>"; + } + + function emailArticle() { + + $param = db_escape_string($_REQUEST['param']); + + require_once "lib/MiniTemplator.class.php"; + + $tpl = new MiniTemplator; + $tpl_t = new MiniTemplator; + + $tpl->readTemplateFromFile("templates/email_article_template.txt"); + + $tpl->setVariable('USER_NAME', $_SESSION["name"], true); + $tpl->setVariable('USER_EMAIL', $user_email, true); + $tpl->setVariable('TTRSS_HOST', $_SERVER["HTTP_HOST"], true); + + + $result = db_query("SELECT link, content, title + FROM ttrss_user_entries, ttrss_entries WHERE id = ref_id AND + id IN ($param) AND owner_uid = " . $_SESSION["uid"]); + + if (db_num_rows($result) > 1) { + $subject = __("[Forwarded]") . " " . __("Multiple articles"); + } + + while ($line = db_fetch_assoc($result)) { + + if (!$subject) + $subject = __("[Forwarded]") . " " . htmlspecialchars($line["title"]); + + $tpl->setVariable('ARTICLE_TITLE', strip_tags($line["title"])); + $tpl->setVariable('ARTICLE_URL', strip_tags($line["link"])); + + $tpl->addBlock('article'); + } + + $tpl->addBlock('email'); + + $content = ""; + $tpl->generateOutputToString($content); + + $mailto_link = htmlspecialchars("mailto: ?subject=".rawurlencode($subject). + "&body=".rawurlencode($content)); + + print __("Clicking the following link to invoke your mail client:"); + + print "<div class=\"tagCloudContainer\">"; + print "<a target=\"_blank\" href=\"$mailto_link\">". + __("Forward selected article(s) by email.")."</a>"; + print "</div>"; + + print __("You should be able to edit the message before sending in your mail client."); + + print "<p>"; + + print "<div style='text-align : center'>"; + print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('emailArticleDlg').hide()\">".__('Close this dialog')."</button>"; + print "</div>"; + + //return; + } + + function api_version() { + return 2; + } + +} +?> diff --git a/plugins/mailto/mail.png b/plugins/mailto/mail.png Binary files differnew file mode 100644 index 000000000..fcdcbd604 --- /dev/null +++ b/plugins/mailto/mail.png diff --git a/plugins/mark_button/init.php b/plugins/mark_button/init.php new file mode 100644 index 000000000..971b12932 --- /dev/null +++ b/plugins/mark_button/init.php @@ -0,0 +1,43 @@ +<?php +class Mark_Button extends Plugin { + private $host; + + function init($host) { + $this->host = $host; + + $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); + } + + function about() { + return array(1.0, + "Bottom un/star button for the combined mode", + "fox"); + } + + function hook_article_button($line) { + $marked_pic = ""; + $id = $line["id"]; + + if (get_pref("COMBINED_DISPLAY_MODE")) { + if (sql_bool_to_bool($line["marked"])) { + $marked_pic = "<img + src=\"images/mark_set.svg\" + class=\"markedPic\" alt=\"Unstar article\" + onclick='toggleMark($id)'>"; + } else { + $marked_pic = "<img + src=\"images/mark_unset.svg\" + class=\"markedPic\" alt=\"Star article\" + onclick='toggleMark($id)'>"; + } + } + + return $marked_pic; + } + + function api_version() { + return 2; + } + +} +?> diff --git a/plugins/note/init.php b/plugins/note/init.php index 560796a69..2a32961fc 100644 --- a/plugins/note/init.php +++ b/plugins/note/init.php @@ -1,6 +1,5 @@ <?php class Note extends Plugin { - private $link; private $host; function about() { @@ -10,7 +9,6 @@ class Note extends Plugin { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); @@ -22,7 +20,7 @@ class Note extends Plugin { function hook_article_button($line) { - return "<img src=\"".theme_image($this->link, "plugins/note/note.png")."\" + return "<img src=\"plugins/note/note.png\" style=\"cursor : pointer\" style=\"cursor : pointer\" onclick=\"editArticleNote(".$line["id"].")\" class='tagsPic' title='".__('Edit article note')."'>"; @@ -31,7 +29,7 @@ class Note extends Plugin { function edit() { $param = db_escape_string($_REQUEST['param']); - $result = db_query($this->link, "SELECT note FROM ttrss_user_entries WHERE + $result = db_query("SELECT note FROM ttrss_user_entries WHERE ref_id = '$param' AND owner_uid = " . $_SESSION['uid']); $note = db_fetch_result($result, 0, "note"); @@ -61,7 +59,7 @@ class Note extends Plugin { $id = db_escape_string($_REQUEST["id"]); $note = trim(strip_tags(db_escape_string($_REQUEST["note"]))); - db_query($this->link, "UPDATE ttrss_user_entries SET note = '$note' + db_query("UPDATE ttrss_user_entries SET note = '$note' WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]); $formatted_note = format_article_note($id, $note); @@ -70,5 +68,9 @@ class Note extends Plugin { "raw_length" => mb_strlen($note))); } + function api_version() { + return 2; + } + } ?> diff --git a/plugins/nsfw/init.php b/plugins/nsfw/init.php index 9aadde4dd..a57aa4456 100644 --- a/plugins/nsfw/init.php +++ b/plugins/nsfw/init.php @@ -1,7 +1,5 @@ <?php class NSFW extends Plugin { - - private $link; private $host; function about() { @@ -12,7 +10,6 @@ class NSFW extends Plugin { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_RENDER_ARTICLE, $this); @@ -101,5 +98,9 @@ class NSFW extends Plugin { echo __("Configuration saved."); } + function api_version() { + return 2; + } + } ?> diff --git a/plugins/owncloud/init.php b/plugins/owncloud/init.php deleted file mode 100644 index b846241b8..000000000 --- a/plugins/owncloud/init.php +++ /dev/null @@ -1,96 +0,0 @@ -<?php -require_once "config.php"; - -class OwnCloud extends Plugin { - private $link; - private $host; - - function about() { - return array(1.0, - "Adds support for OwnCloud ReadLater", - "cy8aer"); - } - - function init($host) { - $this->link = $host->get_link(); - $this->host = $host; - - $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); - $host->add_hook($host::HOOK_PREFS_TAB, $this); - } - - function save() { - $owncloud_url = db_escape_string($_POST["owncloud_url"]); - $this->host->set($this, "owncloud", $owncloud_url); - echo "Value set to $owncloud_url"; - } - - function get_js() { - return file_get_contents(dirname(__FILE__) . "/owncloud.js"); - } - - function hook_prefs_tab($args) { - if ($args != "prefPrefs") return; - - print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__("Owncloud")."\">"; - - print "<br/>"; - - $value = $this->host->get($this, "owncloud"); - print "<form dojoType=\"dijit.form.Form\">"; - - print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\"> - evt.preventDefault(); - if (this.validate()) { - console.log(dojo.objectToQuery(this.getValues())); - new Ajax.Request('backend.php', { - parameters: dojo.objectToQuery(this.getValues()), - onComplete: function(transport) { - notify_info(transport.responseText); - } - }); - } - </script>"; - - print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pluginhandler\">"; - print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"save\">"; - print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"plugin\" value=\"owncloud\">"; - print "<table width=\"100%\" class=\"prefPrefsList\">"; - print "<tr><td width=\"40%\">".__("Owncloud url")."</td>"; - print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" name=\"owncloud_url\" regExp='^(http|https)://.*' value=\"$value\"></td></tr>"; - print "</table>"; - print "<p><button dojoType=\"dijit.form.Button\" type=\"submit\">".__("Save")."</button>"; - - print "</form>"; - - print "</div>"; #pane - - } - - function hook_article_button($line) { - return "<img src=\"".theme_image($this->link, "plugins/owncloud/owncloud.png")."\" - style=\"cursor : pointer\" style=\"cursor : pointer\" - onclick=\"ownArticle(".$line["id"].")\" - class='tagsPic' title='".__('Bookmark on OwnCloud ')."'>"; - } - - function getOwnCloud() { - $id = db_escape_string($_REQUEST['id']); - - $result = db_query($this->link, "SELECT title, link - FROM ttrss_entries, ttrss_user_entries - WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']); - - if (db_num_rows($result) != 0) { - $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')), - 100, '...'); - $article_link = db_fetch_result($result, 0, 'link'); - } - - $own_url = $this->host->get($this, "owncloud"); - - print json_encode(array("title" => $title, "link" => $article_link, - "id" => $id, "ownurl" => $own_url)); - } -} -?> diff --git a/plugins/owncloud/owncloud.js b/plugins/owncloud/owncloud.js deleted file mode 100644 index 6e971030b..000000000 --- a/plugins/owncloud/owncloud.js +++ /dev/null @@ -1,26 +0,0 @@ -function ownArticle(id) { - try { - var query = "?op=pluginhandler&plugin=owncloud&method=getOwnCloud&id=" + param_escape(id); - - console.log(query); - - var d = new Date(); - var ts = d.getTime(); - - var w = window.open('backend.php?op=backend&method=loading', 'ttrss_tweet', - "status=0,toolbar=0,location=0,width=600,height=500,scrollbars=1,menubar=0"); - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - var ti = JSON.parse(transport.responseText); - - var share_url = ti.ownurl + "?app=bookmarks&getfile=addBm.php?output=popup&url=" + param_escape(ti.link); - - w.location.href = share_url; - } }); - } catch (e) { - exception_error("ownArticle", e); - } -} - diff --git a/plugins/owncloud/owncloud.png b/plugins/owncloud/owncloud.png Binary files differdeleted file mode 100644 index d31ba924b..000000000 --- a/plugins/owncloud/owncloud.png +++ /dev/null diff --git a/plugins/pinterest/init.php b/plugins/pinterest/init.php deleted file mode 100644 index aef9d8511..000000000 --- a/plugins/pinterest/init.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -class Pinterest extends Plugin { - private $link; - private $host; - - function about() { - return array(1.0, - "Share article on Pinterest", - "?"); - } - - function init($host) { - $this->link = $host->get_link(); - $this->host = $host; - - $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); - } - - function get_js() { - return file_get_contents(dirname(__FILE__) . "/pinterest.js"); - } - - function hook_article_button($line) { - $article_id = $line["id"]; - - $rv = "<img src=\"".theme_image($this->link, 'plugins/pinterest/pinterest.png')."\" - class='tagsPic' style=\"cursor : pointer\" - onclick=\"pinterest($article_id)\" - title='".__('Pinterest')."'>"; - - return $rv; - } - - function getInfo() { - $id = db_escape_string($_REQUEST['id']); - - $result = db_query($this->link, "SELECT title, link - FROM ttrss_entries, ttrss_user_entries - WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']); - - if (db_num_rows($result) != 0) { - $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')), - 100, '...'); - $article_link = db_fetch_result($result, 0, 'link'); - } - - print json_encode(array("title" => $title, "link" => $article_link, - "id" => $id)); - } - - -} -?> diff --git a/plugins/pinterest/pinterest.js b/plugins/pinterest/pinterest.js deleted file mode 100644 index 01c525f55..000000000 --- a/plugins/pinterest/pinterest.js +++ /dev/null @@ -1,31 +0,0 @@ - function pinterest(id) { - try { - var query = "?op=pluginhandler&plugin=pinterest&method=getInfo&id=" + param_escape(id); - - console.log(query); - - var d = new Date(); - var ts = d.getTime(); - - var w = window.open('backend.php?op=backend&method=loading', 'ttrss_tweet', - "status=0,toolbar=0,location=0,width=650,height=600,scrollbars=1,menubar=0"); - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - var ti = JSON.parse(transport.responseText); - - var share_url = "http://pinterest.com/pin/create/button/?" + - "url=" + param_escape(ti.link) + - "&description=" + param_escape(ti.title); - - w.location.href = share_url; - - } }); - - - } catch (e) { - exception_error("tweetArticle", e); - } - } - diff --git a/plugins/pinterest/pinterest.png b/plugins/pinterest/pinterest.png Binary files differdeleted file mode 100644 index b85aed3cd..000000000 --- a/plugins/pinterest/pinterest.png +++ /dev/null diff --git a/plugins/pocket/init.php b/plugins/pocket/init.php deleted file mode 100644 index 3fc51dd91..000000000 --- a/plugins/pocket/init.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -class Pocket extends Plugin { - - private $link; - private $host; - - function about() { - return array(1.0, - "Share article on Pocket (formerly Read It Later)", - "?"); - } - - function init($host) { - $this->link = $host->get_link(); - $this->host = $host; - - $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); - } - - function get_js() { - return file_get_contents(dirname(__FILE__) . "/pocket.js"); - } - - function hook_article_button($line) { - $article_id = $line["id"]; - - $rv = "<img src=\"".theme_image($this->link, 'plugins/pocket/pocket.png')."\" - class='tagsPic' style=\"cursor : pointer\" - onclick=\"shareArticleToPocket($article_id)\" - title='".__('Pocket')."'>"; - - return $rv; - } - - function getInfo() { - $id = db_escape_string($_REQUEST['id']); - - $result = db_query($this->link, "SELECT title, link - FROM ttrss_entries, ttrss_user_entries - WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']); - - if (db_num_rows($result) != 0) { - $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')), - 100, '...'); - $article_link = db_fetch_result($result, 0, 'link'); - } - - print json_encode(array("title" => $title, "link" => $article_link, - "id" => $id)); - } - - -} -?> diff --git a/plugins/pocket/pocket.js b/plugins/pocket/pocket.js deleted file mode 100644 index 021d5bb05..000000000 --- a/plugins/pocket/pocket.js +++ /dev/null @@ -1,31 +0,0 @@ - function shareArticleToPocket(id) { - try { - var query = "?op=pluginhandler&plugin=pocket&method=getInfo&id=" + param_escape(id); - - console.log(query); - - var d = new Date(); - var ts = d.getTime(); - - var w = window.open('backend.php?op=backend&method=loading', 'ttrss_tweet', - "status=0,toolbar=0,location=0,width=500,height=400,scrollbars=1,menubar=0"); - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - var ti = JSON.parse(transport.responseText); - - var share_url = "https://getpocket.com/save?" + - "&title=" + param_escape(ti.title) + - "&url=" + param_escape(ti.link); - - w.location.href = share_url; - - } }); - - - } catch (e) { - exception_error("tweetArticle", e); - } - } - diff --git a/plugins/pocket/pocket.png b/plugins/pocket/pocket.png Binary files differdeleted file mode 100644 index ff6bc85a4..000000000 --- a/plugins/pocket/pocket.png +++ /dev/null diff --git a/plugins/share/init.php b/plugins/share/init.php index e1151849b..72a4d4bf9 100644 --- a/plugins/share/init.php +++ b/plugins/share/init.php @@ -1,6 +1,5 @@ <?php class Share extends Plugin { - private $link; private $host; function about() { @@ -10,7 +9,6 @@ class Share extends Plugin { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); @@ -21,7 +19,7 @@ class Share extends Plugin { } function hook_article_button($line) { - return "<img src=\"".theme_image($this->link, 'plugins/share/share.png')."\" + return "<img src=\"plugins/share/share.png\" class='tagsPic' style=\"cursor : pointer\" onclick=\"shareArticle(".$line['int_id'].")\" title='".__('Share by URL')."'>"; @@ -30,7 +28,7 @@ class Share extends Plugin { function shareArticle() { $param = db_escape_string($_REQUEST['param']); - $result = db_query($this->link, "SELECT uuid, ref_id FROM ttrss_user_entries WHERE int_id = '$param' + $result = db_query("SELECT uuid, ref_id FROM ttrss_user_entries WHERE int_id = '$param' AND owner_uid = " . $_SESSION['uid']); if (db_num_rows($result) == 0) { @@ -42,11 +40,11 @@ class Share extends Plugin { if (!$uuid) { $uuid = db_escape_string(sha1(uniqid(rand(), true))); - db_query($this->link, "UPDATE ttrss_user_entries SET uuid = '$uuid' WHERE int_id = '$param' + db_query("UPDATE ttrss_user_entries SET uuid = '$uuid' WHERE int_id = '$param' AND owner_uid = " . $_SESSION['uid']); } - print __("You can share this article by the following unique URL:"); + print "<h2>". __("You can share this article by the following unique URL:") . "</h2>"; $url_path = get_self_url_prefix(); $url_path .= "/public.php?op=share&key=$uuid"; @@ -55,10 +53,10 @@ class Share extends Plugin { print "<a id='pub_opml_url' href='$url_path' target='_blank'>$url_path</a>"; print "</div>"; - /* if (!label_find_id($this->link, __('Shared'), $_SESSION["uid"])) - label_create($this->link, __('Shared'), $_SESSION["uid"]); + /* if (!label_find_id(__('Shared'), $_SESSION["uid"])) + label_create(__('Shared'), $_SESSION["uid"]); - label_add_article($this->link, $ref_id, __('Shared'), $_SESSION['uid']); */ + label_add_article($ref_id, __('Shared'), $_SESSION['uid']); */ } print "<div align='center'>"; @@ -69,6 +67,9 @@ class Share extends Plugin { print "</div>"; } + function api_version() { + return 2; + } } ?> diff --git a/plugins/swap_jk/init.php b/plugins/swap_jk/init.php index 34b09bd77..e60e7201f 100644 --- a/plugins/swap_jk/init.php +++ b/plugins/swap_jk/init.php @@ -1,7 +1,6 @@ <?php class Swap_JK extends Plugin { - private $link; private $host; function about() { @@ -11,7 +10,6 @@ class Swap_JK extends Plugin { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_HOTKEY_MAP, $this); @@ -23,7 +21,11 @@ class Swap_JK extends Plugin { $hotkeys["k"] = "prev_feed"; return $hotkeys; + } + function api_version() { + return 2; } + } ?> diff --git a/plugins/tweet/init.php b/plugins/tweet/init.php deleted file mode 100644 index e7f8ce949..000000000 --- a/plugins/tweet/init.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -class Tweet extends Plugin { - private $link; - private $host; - - function init($host) { - $this->link = $host->get_link(); - $this->host = $host; - - $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); - } - - function about() { - return array(1.0, - "Share article on Twitter", - "fox"); - } - - function get_js() { - return file_get_contents(dirname(__FILE__) . "/tweet.js"); - } - - function hook_article_button($line) { - $article_id = $line["id"]; - - $rv = "<img src=\"".theme_image($this->link, 'plugins/tweet/tweet.png')."\" - class='tagsPic' style=\"cursor : pointer\" - onclick=\"tweetArticle($article_id)\" - title='".__('Share on Twitter')."'>"; - - return $rv; - } - - function getInfo() { - $id = db_escape_string($_REQUEST['id']); - - $result = db_query($this->link, "SELECT title, link - FROM ttrss_entries, ttrss_user_entries - WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']); - - if (db_num_rows($result) != 0) { - $title = truncate_string(strip_tags(db_fetch_result($result, 0, 'title')), - 100, '...'); - $article_link = db_fetch_result($result, 0, 'link'); - } - - print json_encode(array("title" => $title, "link" => $article_link, - "id" => $id)); - } - - -} -?> diff --git a/plugins/tweet/tweet.js b/plugins/tweet/tweet.js deleted file mode 100644 index 07e89d5f8..000000000 --- a/plugins/tweet/tweet.js +++ /dev/null @@ -1,31 +0,0 @@ - function tweetArticle(id) { - try { - var query = "?op=pluginhandler&plugin=tweet&method=getInfo&id=" + param_escape(id); - - console.log(query); - - var d = new Date(); - var ts = d.getTime(); - - var w = window.open('backend.php?op=backend&method=loading', 'ttrss_tweet', - "status=0,toolbar=0,location=0,width=500,height=400,scrollbars=1,menubar=0"); - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - var ti = JSON.parse(transport.responseText); - - var share_url = "http://twitter.com/share?_=" + ts + - "&text=" + param_escape(ti.title) + - "&url=" + param_escape(ti.link); - - w.location.href = share_url; - - } }); - - - } catch (e) { - exception_error("tweetArticle", e); - } - } - diff --git a/plugins/tweet/tweet.png b/plugins/tweet/tweet.png Binary files differdeleted file mode 100644 index ad3c177a2..000000000 --- a/plugins/tweet/tweet.png +++ /dev/null diff --git a/plugins/updater/init.php b/plugins/updater/init.php index d940aefeb..fa283c8be 100644 --- a/plugins/updater/init.php +++ b/plugins/updater/init.php @@ -1,7 +1,6 @@ <?php class Updater extends Plugin { - private $link; private $host; function about() { @@ -12,7 +11,6 @@ class Updater extends Plugin { } function init($host) { - $this->link = $host->get_link(); $this->host = $host; $host->add_hook($host::HOOK_PREFS_TAB, $this); @@ -22,7 +20,7 @@ class Updater extends Plugin { $this); } - function update_self_step($link, $step, $params, $force = false) { + function update_self_step($step, $params, $force = false) { // __FILE__ is in plugins/updater so we need to go one level up $work_dir = dirname(dirname(dirname(__FILE__))); $parent_dir = dirname($work_dir); @@ -42,7 +40,7 @@ class Updater extends Plugin { case 0: array_push($log, "Work directory: $work_dir"); - if (!is_writable($work_dir) && !is_writable("$parent_dir")) { + if (!is_writable($work_dir) || !is_writable("$parent_dir")) { $user = posix_getpwuid(posix_geteuid()); $user = $user["name"]; array_push($log, "Both tt-rss and parent directories should be writable as current user ($user)."); @@ -59,6 +57,10 @@ class Updater extends Plugin { $stop = true; break; } + // bah, also humbug + putenv("PATH=" . getenv("PATH") . PATH_SEPARATOR . "/bin" . + PATH_SEPARATOR . "/usr/bin"); + array_push($log, "Checking for tar..."); $system_rc = 0; @@ -79,7 +81,6 @@ class Updater extends Plugin { $stop = true; break; } - array_push($log, "Checking for latest version..."); $version_info = json_decode(fetch_file_contents("http://tt-rss.org/version.php"), @@ -91,7 +92,7 @@ class Updater extends Plugin { } $target_version = $version_info["version"]; - $target_dir = "$parent_dir/tt-rss-$target_version"; + $target_dir = "$parent_dir/Tiny-Tiny-RSS-$target_version"; array_push($log, "Target version: $target_version"); $params["target_version"] = $target_version; @@ -110,7 +111,7 @@ class Updater extends Plugin { case 1: $target_version = $params["target_version"]; - array_push($log, "Downloading checksums..."); +/* array_push($log, "Downloading checksums..."); $md5sum_data = fetch_file_contents("http://tt-rss.org/download/md5sum.txt"); if (!$md5sum_data) { @@ -134,16 +135,18 @@ class Updater extends Plugin { $stop = true; break; } - $params["target_md5sum"] = $target_md5sum; + $params["target_md5sum"] = $target_md5sum; */ + + array_push($log, "Proceeding to download..."); break; case 2: $target_version = $params["target_version"]; - $target_md5sum = $params["target_md5sum"]; + // $target_md5sum = $params["target_md5sum"]; array_push($log, "Downloading distribution tarball..."); - $tarball_url = "http://tt-rss.org/download/tt-rss-$target_version.tar.gz"; + $tarball_url = "https://github.com/gothfox/Tiny-Tiny-RSS/archive/$target_version.tar.gz"; $data = fetch_file_contents($tarball_url); if (!$data) { @@ -151,14 +154,14 @@ class Updater extends Plugin { $stop = true; break; } - array_push($log, "Verifying tarball checksum..."); + /* array_push($log, "Verifying tarball checksum..."); $test_md5sum = md5($data); if ($test_md5sum != $target_md5sum) { array_push($log, "Downloaded checksum doesn't match (got $test_md5sum, expected $target_md5sum)."); $stop = true; break; - } + } */ $tmp_file = tempnam(sys_get_temp_dir(), 'tt-rss'); array_push($log, "Saving download to $tmp_file"); @@ -180,14 +183,6 @@ class Updater extends Plugin { $stop = true; break; } - $old_dir = tmpdirname($parent_dir, "tt-rss-old"); - - array_push($log, "Renaming tt-rss directory to ".basename($old_dir)); - if (!rename($work_dir, $old_dir)) { - array_push($log, "Unable to rename tt-rss directory."); - $stop = true; break; - } - array_push($log, "Extracting tarball..."); system("tar zxf $tmp_file", $system_rc); @@ -196,7 +191,20 @@ class Updater extends Plugin { $stop = true; break; } - $target_dir = "$parent_dir/tt-rss-$target_version"; + $target_dir = "$parent_dir/Tiny-Tiny-RSS-$target_version"; + + if (!is_dir($target_dir)) { + array_push($log, "Target directory ($target_dir) not found."); + $stop = true; break; + } + + $old_dir = tmpdirname($parent_dir, "tt-rss-old"); + + array_push($log, "Renaming tt-rss directory to ".basename($old_dir)); + if (!rename($work_dir, $old_dir)) { + array_push($log, "Unable to rename tt-rss directory."); + $stop = true; break; + } array_push($log, "Renaming target directory..."); if (!rename($target_dir, $work_dir)) { @@ -224,6 +232,7 @@ class Updater extends Plugin { CACHE_DIR, CACHE_DIR . "/export", CACHE_DIR . "/images", + CACHE_DIR . "/js", CACHE_DIR . "/simplepie", ICONS_DIR, LOCK_DIRECTORY); @@ -233,6 +242,26 @@ class Updater extends Plugin { chmod($dir, 0777); } + if (ICONS_DIR == "feed-icons") { + array_push($log, "Migrating feed icons..."); + + $icons = glob("$old_dir/feed-icons/*.ico"); + $icons_copied = 0; + + foreach ($icons as $icon) { + $icon = basename($icon); + + if (copy("$old_dir/feed-icons/$icon", "$work_dir/feed-icons/$icon")) { + ++$icons_copied; + } + } + + array_push($log, "Done; $icons_copied files copied"); + + } else { + array_push($log, "Not migrating feed icons, ICONS_DIR modified."); + } + array_push($log, "Upgrade completed."); array_push($log, "Your old tt-rss directory is saved at $old_dir. ". "Please migrate locally modified files (if any) and remove it."); @@ -248,13 +277,13 @@ class Updater extends Plugin { return array("step" => $step, "stop" => $stop, "params" => $params, "log" => $log); } - function update_self_cli($link, $force = false) { + function update_self_cli($force = false) { $step = 0; $stop = false; $params = array(); while (!$stop) { - $rc = $this->update_self_step($link, $step, $params, $force); + $rc = $this->update_self_step($step, $params, $force); $params = $rc['params']; $stop = $rc['stop']; @@ -267,14 +296,18 @@ class Updater extends Plugin { } function update_self($args) { - _debug("Warning: self-updating is experimental. Use at your own risk."); - _debug("Please backup your tt-rss directory before continuing. Your database will not be modified."); + _debug("READ THE FOLLOWING BEFORE CONTINUING!"); + _debug("* It is suggested to backup your tt-rss directory first."); + _debug("* Your database will not be modified."); + _debug("* Your current tt-rss installation directory will not be modified. It will be renamed and left in the parent directory. You will be able to migrate all your customized files after update finishes."); _debug("Type 'yes' to continue."); - if (read_stdin() != 'yes') + $input = read_stdin(); + + if ($input != 'yes' && $input != 'force') exit; - $this->update_self_cli($link, in_array("-force", $args)); + $this->update_self_cli($input == 'force'); } function get_prefs_js() { @@ -288,15 +321,20 @@ class Updater extends Plugin { print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Update Tiny Tiny RSS')."\">"; if ($_SESSION["pref_last_version_check"] + 86400 + rand(-1000, 1000) < time()) { - $_SESSION["version_data"] = @check_for_update($this->link); + $_SESSION["version_data"] = @check_for_update(); $_SESSION["pref_last_version_check"] = time(); } if (is_array($_SESSION["version_data"])) { $version = $_SESSION["version_data"]["version"]; + $version_id = $_SESSION["version_data"]["version_id"]; print_notice(T_sprintf("New version of Tiny Tiny RSS is available (%s).", "<b>$version</b>")); - print "<p><button dojoType=\"dijit.form.Button\" onclick=\"return updateSelf()\">". + $details = "http://tt-rss.org/redmine/versions/$version_id"; + + print "<p><button onclick=\"window.open('$details')\" dojoType=\"dijit.form.Button\">".__("See the release notes")."</button>"; + + print " <button dojoType=\"dijit.form.Button\" onclick=\"return updateSelf()\">". __('Update Tiny Tiny RSS')."</button></p>"; } else { @@ -308,11 +346,18 @@ class Updater extends Plugin { } function updateSelf() { + print_warning(__("Do not close this dialog until updating is finished.")); + print "<form style='display : block' name='self_update_form' id='self_update_form'>"; - print "<div class='error'>".__("Do not close this dialog until updating is finished. Backup your tt-rss directory before continuing.")."</div>"; + print "<style type='text/css'> + li.notice { font-style : italic; color : red; } + </style>"; print "<ul class='selfUpdateList' id='self_update_log'>"; + print "<li class='notice'>" .__("It is suggested to backup your tt-rss directory first.") . "</li>"; + print "<li class='notice'>" . __("Your database will not be modified.") . "</li>"; + print "<li class='notice'>" . __("Your current tt-rss installation directory will not be modified. It will be renamed and left in the parent directory. You will be able to migrate all your customized files after update finishes.") . "</li>"; print "<li>" . __("Ready to update.") . "</li>"; print "</ul>"; @@ -331,9 +376,13 @@ class Updater extends Plugin { $force = (bool) $_REQUEST["force"]; if (($_SESSION["access_level"] >= 10 || SINGLE_USER_MODE) && CHECK_FOR_NEW_VERSION) { - print json_encode($this->update_self_step($this->link, $step, $params, $force)); + print json_encode($this->update_self_step($step, $params, $force)); } } + function api_version() { + return 2; + } + } ?> diff --git a/plugins/updater/updater.js b/plugins/updater/updater.js index 17452d734..4a1847372 100644 --- a/plugins/updater/updater.js +++ b/plugins/updater/updater.js @@ -16,7 +16,7 @@ function updateSelf() { notify_progress("Loading, please wait...", true); new Ajax.Request("backend.php", { - parameters: "?op=pluginhandler&plugin=updater&method=performUpdate&step=" + step + + parameters: "op=pluginhandler&plugin=updater&method=performUpdate&step=" + step + "¶ms=" + param_escape(JSON.stringify(dialog.attr("update-params"))), onComplete: function(transport) { try { @@ -55,7 +55,7 @@ function updateSelf() { } }, start: function() { - if (prompt(__("Live updating is considered experimental. Backup your tt-rss directory before continuing. Please type 'yes' to continue.")) == 'yes') { + if (prompt(__("Backup your tt-rss directory before continuing. Please type 'yes' to continue.")) == 'yes') { dialog.performUpdate(0); } }, |