//define('MAGPIE_USER_AGENT_EXT', ' (Tiny Tiny RSS/' . VERSION . ')');
define('MAGPIE_OUTPUT_ENCODING', 'UTF-8');
- define('MAGPIE_CACHE_AGE', 60*15); // 15 minutes
define('SELF_USER_AGENT', 'Tiny Tiny RSS/' . VERSION . ' (http://tt-rss.org/)');
define('MAGPIE_USER_AGENT', SELF_USER_AGENT);
require_once "lib/magpierss/rss_fetch.inc";
require_once 'lib/magpierss/rss_utils.inc';
require_once 'lib/htmlpurifier/library/HTMLPurifier.auto.php';
+ require_once 'lib/pubsubhubbub/publisher.php';
+ require_once 'lib/pubsubhubbub/subscriber.php';
$config = HTMLPurifier_Config::createDefault();
- $allowed = "p,a[href],i,em,b,strong,code,pre,blockquote,br,img[src|alt|title],ul,ol,li,h1,h2,h3,h4,s";
+ $allowed = "p,a[href],i,em,b,strong,code,pre,blockquote,br,img[src|alt|title],ul,ol,li,h1,h2,h3,h4,s,object[classid|type|id|name|width|height|codebase],param[name|value]";
+ $config->set('HTML.SafeObject', true);
$config->set('HTML', 'Allowed', $allowed);
+ $config->set('Output.FlashCompat', true);
+ $config->set('Attr.EnableID', true);
+
$purifier = new HTMLPurifier($config);
/**
}
}
- function update_rss_feed($link, $feed, $ignore_daemon = false) {
+ function update_rss_feed($link, $feed, $ignore_daemon = false, $no_cache = false) {
global $memcache;
WHERE f2.feed_url = f1.feed_url AND f2.id = '$feed'");
while ($line = db_fetch_assoc($result)) {
- update_rss_feed_real($link, $line["id"], $ignore_daemon);
+ update_rss_feed_real($link, $line["id"], $ignore_daemon, $no_cache);
}
} else {
- update_rss_feed_real($link, $feed, $ignore_daemon);
+ update_rss_feed_real($link, $feed, $ignore_daemon, $no_cache);
}
}
- function update_rss_feed_real($link, $feed, $ignore_daemon = false) {
+ function update_rss_feed_real($link, $feed, $ignore_daemon = false, $no_cache = false) {
global $memcache;
$result = db_query($link, "SELECT id,update_interval,auth_login,
feed_url,auth_pass,cache_images,update_method,last_updated,
- owner_uid
+ mark_unread_on_update, owner_uid, update_on_checksum_change,
+ pubsub_state
FROM ttrss_feeds WHERE id = '$feed'");
}
$update_method = db_fetch_result($result, 0, "update_method");
$last_updated = db_fetch_result($result, 0, "last_updated");
$owner_uid = db_fetch_result($result, 0, "owner_uid");
+ $mark_unread_on_update = sql_bool_to_bool(db_fetch_result($result,
+ 0, "mark_unread_on_update"));
+ $update_on_checksum_change = sql_bool_to_bool(db_fetch_result($result,
+ 0, "update_on_checksum_change"));
+ $pubsub_state = db_fetch_result($result, 0, "pubsub_state");
db_query($link, "UPDATE ttrss_feeds SET last_update_started = NOW()
WHERE id = '$feed'");
if ($update_method == 3) {
$rss = fetch_twitter_rss($link, $fetch_url, $owner_uid);
- } else if ($update_method == 1) {
+ } else if ($update_method == 1) {
+
+ define('MAGPIE_CACHE_AGE', get_feed_update_interval($link, $feed) * 60);
+ define('MAGPIE_CACHE_ON', !$no_cache);
+
$rss = @fetch_rss($fetch_url);
} else {
if (!is_dir(SIMPLEPIE_CACHE_DIR)) {
get_feed_update_interval($link, $feed)*60);
}
- if (is_dir(SIMPLEPIE_CACHE_DIR)) {
+ $rss->enable_cache(!$no_cache);
+
+ if (!$no_cache) {
$rss->set_cache_location(SIMPLEPIE_CACHE_DIR);
$rss->set_cache_duration(get_feed_update_interval($link, $feed) * 60);
}
$filters = load_filters($link, $feed, $owner_uid);
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug'] == 2) {
print_r($filters);
}
return; // no articles
}
+ if ($pubsub_state != 2) {
+
+ $feed_hub_url = false;
+ if ($use_simplepie) {
+ $links = $rss->get_links('hub');
+
+ if ($links && is_array($links)) {
+ foreach ($links as $l) {
+ $feed_hub_url = $l;
+ break;
+ }
+ }
+
+ } else {
+ $atom = $rss->channel['atom'];
+
+ if ($atom) {
+ if ($atom['link@rel'] == 'hub') {
+ $feed_hub_url = $atom['link@href'];
+ }
+
+ if (!$feed_hub_url && $atom['link#'] > 1) {
+ for ($i = 2; $i <= $atom['link#']; $i++) {
+ if ($atom["link#$i@rel"] == 'hub') {
+ $feed_hub_url = $atom["link#$i@href"];
+ break;
+ }
+ }
+ }
+ } else {
+ $feed_hub_url = $rss->channel['link_hub'];
+ }
+ }
+
+ if ($feed_hub_url && function_exists('curl_init')) {
+ $callback_url = get_self_url_prefix() .
+ "/backend.php?op=pubsub&id=$feed";
+
+ $s = new Subscriber($feed_hub_url, $callback_url);
+
+ $s->subscribe($fetch_url);
+
+ db_query($link, "UPDATE ttrss_feeds SET pubsub_state = 1
+ WHERE id = '$feed'");
+ }
+ }
+
if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
_debug("update_rss_feed: processing articles...");
}
VALUES ('$ref_id', '$owner_uid', '$feed', $unread,
$last_read_qpart, $marked, $published, '$score', '', '')");
+ if (PUBSUBHUBBUB_HUB && $published == 'true') {
+ $rss_link = get_self_url_prefix() .
+ "/backend.php?op=rss&id=-2&key=" .
+ get_feed_access_key($link, -2, false, $owner_uid);
+
+ $p = new Publisher(PUBSUBHUBBUB_HUB);
+
+ $pubsub_result = $p->publish_update($rss_link);
+ }
+
$result = db_query($link,
"SELECT int_id FROM ttrss_user_entries WHERE
ref_id = '$ref_id' AND owner_uid = '$owner_uid' AND
$post_needs_update = false;
- if (get_pref($link, "UPDATE_POST_ON_CHECKSUM_CHANGE", $owner_uid, false) &&
- ($content_hash != $orig_content_hash)) {
+ if ($content_hash != $orig_content_hash) {
// print "<!-- [$entry_title] $content_hash vs $orig_content_hash -->";
$post_needs_update = true;
}
db_query($link, "UPDATE ttrss_entries
SET title = '$entry_title', content = '$entry_content',
content_hash = '$content_hash',
+ updated = '$entry_timestamp_fmt',
num_comments = '$num_comments'
WHERE id = '$ref_id'");
- if (get_pref($link, "MARK_UNREAD_ON_UPDATE", $owner_uid, false)) {
+ if ($mark_unread_on_update) {
db_query($link, "UPDATE ttrss_user_entries
SET last_read = null, unread = true WHERE ref_id = '$ref_id'");
- } else {
+ } else if ($update_on_checksum_change) {
db_query($link, "UPDATE ttrss_user_entries
SET last_read = null WHERE ref_id = '$ref_id' AND unread = false");
}
return "";
}
- function get_remote_user() {
- $remote_user = "";
+ function get_remote_user($link) {
if (defined('ALLOW_REMOTE_USER_AUTH') && ALLOW_REMOTE_USER_AUTH) {
- $remote_user = $_SERVER["REMOTE_USER"];
+ return db_escape_string($_SERVER["REMOTE_USER"]);
}
- return db_escape_string($remote_user);
+ return db_escape_string(get_login_by_ssl_certificate($link));
}
- function get_remote_fakepass() {
- if (get_remote_user())
+ function get_remote_fakepass($link) {
+ if (get_remote_user($link))
return "******";
else
return "";
$pwd_hash2 = encrypt_password($password, $login);
$login = db_escape_string($login);
- $remote_user = get_remote_user();
-
- if (!$remote_user)
- $remote_user = get_login_by_ssl_certificate($link);
+ $remote_user = get_remote_user($link);
- if ($remote_user && $login != "admin") {
+ if ($remote_user && $remote_user == $login && $login != "admin") {
$login = $remote_user;
FROM ttrss_users WHERE
login = '$login'";
+ if (defined('AUTO_CREATE_USER') && AUTO_CREATE_USER
+ && $_SERVER["REMOTE_USER"]) {
+ $result = db_query($link, $query);
+
+ // First login ?
+ if (db_num_rows($result) == 0) {
+ $query = "INSERT INTO ttrss_users
+ (login,access_level,last_login,created)
+ VALUES ('$login', 0, null, NOW())";
+ db_query($link, $query);
+ }
+ }
+
} else {
$query = "SELECT id,login,access_level,pwd_hash
FROM ttrss_users WHERE
db_query($link, "UPDATE ttrss_users SET last_login = NOW() WHERE id = " .
$_SESSION["uid"]);
+
+ // LemonLDAP can send user informations via HTTP HEADER
+ if (defined('AUTO_CREATE_USER') && AUTO_CREATE_USER){
+ // update user name
+ if ($_SERVER['HTTP_USER_NAME']){
+ $fullname = db_escape_string($_SERVER['HTTP_USER_NAME']);
+ db_query($link, "UPDATE ttrss_users SET full_name = '$fullname' WHERE id = " .
+ $_SESSION["uid"]);
+ }
+ // update user mail
+ if ($_SERVER['HTTP_USER_MAIL']){
+ $email = db_escape_string($_SERVER['HTTP_USER_MAIL']);
+ db_query($link, "UPDATE ttrss_users SET email = '$email' WHERE id = " .
+ $_SESSION["uid"]);
+ }
+ }
+
$_SESSION["ip_address"] = $_SERVER["REMOTE_ADDR"];
$_SESSION["pwd_hash"] = db_fetch_result($result, 0, "pwd_hash");
}
if (!$_SESSION["uid"] || !validate_session($link)) {
- $cert_login = get_login_by_ssl_certificate($link);
- if ($cert_login) {
- authenticate_user($link, $cert_login, null);
- $_SESSION["ref_schema_version"] = get_schema_version($link, true);
- } else if (get_remote_user() && AUTO_LOGIN) {
- authenticate_user($link, get_remote_user(), null);
+ if (get_remote_user($link) && AUTO_LOGIN) {
+ authenticate_user($link, get_remote_user($link), null);
$_SESSION["ref_schema_version"] = get_schema_version($link, true);
} else {
render_login_form($link, $mobile);
$params["theme"] = get_user_theme($link);
$params["theme_options"] = get_user_theme_options($link);
- $params["daemon_enabled"] = ENABLE_UPDATE_DAEMON;
$params["sign_progress"] = theme_image($link, "images/indicator_white.gif");
$params["sign_progress_tiny"] = theme_image($link, "images/indicator_tiny.gif");
$data['last_article_id'] = getLastArticleId($link);
$data['cdm_expanded'] = get_pref($link, 'CDM_EXPANDED');
- if (ENABLE_UPDATE_DAEMON) {
+ if (file_exists(LOCK_DIRECTORY . "/update_daemon.lock")) {
$data['daemon_is_running'] = (int) file_is_locked("update_daemon.lock");
function generate_syndicated_feed($link, $owner_uid, $feed, $is_cat,
$limit, $search, $search_mode, $match_on, $view_mode = false) {
+ require_once "lib/MiniTemplator.class.php";
+
$note_style = "float : right; background-color : #fff7d5; border-width : 1px; ".
"padding : 5px; border-style : dashed; border-color : #e7d796;".
"margin-bottom : 1em; color : #9a8c59;";
$feed_site_url = $qfh_ret[2];
$last_error = $qfh_ret[3];
-// if (!$feed_site_url) $feed_site_url = "http://localhost/";
+ $feed_self_url = get_self_url_prefix() .
+ "/backend.php?op=rss&id=-2&key=" .
+ get_feed_access_key($link, -2, false);
- print "<?xml version=\"1.0\" encoding=\"utf-8\"?>
- <?xml-stylesheet type=\"text/xsl\" href=\"rss.xsl\"?>
- <rss version=\"2.0\">
- <channel>
- <title>$feed_title</title>
- <link>$feed_site_url</link>
- <description>Feed generated by Tiny Tiny RSS</description>";
+ if (!$feed_site_url) $feed_site_url = get_self_url_prefix();
- while ($line = db_fetch_assoc($result)) {
- print "<item>";
- print "<guid>" . htmlspecialchars($line["guid"]) . "</guid>";
- print "<link>" . htmlspecialchars($line["link"]) . "</link>";
+ $tpl = new MiniTemplator;
- $tags = get_article_tags($link, $line["id"], $owner_uid);
+ $tpl->readTemplateFromFile("templates/generated_feed.txt");
- foreach ($tags as $tag) {
- print "<category>" . htmlspecialchars($tag) . "</category>";
- }
+ $tpl->setVariable('FEED_TITLE', $feed_title);
+ $tpl->setVariable('VERSION', VERSION);
+ $tpl->setVariable('FEED_URL', htmlspecialchars($feed_self_url));
+
+ if (PUBSUBHUBBUB_HUB && $feed == -2) {
+ $tpl->setVariable('HUB_URL', htmlspecialchars(PUBSUBHUBBUB_HUB));
+ $tpl->addBlock('feed_hub');
+ }
- $rfc822_date = date('r', strtotime($line["updated"]));
+ $tpl->setVariable('SELF_URL', htmlspecialchars(get_self_url_prefix()));
- print "<pubDate>$rfc822_date</pubDate>";
+ while ($line = db_fetch_assoc($result)) {
+ $tpl->setVariable('ARTICLE_ID', htmlspecialchars($line['link']));
+ $tpl->setVariable('ARTICLE_LINK', htmlspecialchars($line['link']));
+ $tpl->setVariable('ARTICLE_TITLE', htmlspecialchars($line['title']));
+ $tpl->setVariable('ARTICLE_EXCERPT',
+ truncate_string(strip_tags($line["content_preview"]), 100, '...'));
+
+ $content = sanitize_rss($link, $line["content_preview"], false, $owner_uid);
- if ($line["author"]) {
- print "<author>" . htmlspecialchars($line["author"]) . "</author>";
+ if ($line['note']) {
+ $content = "<div style=\"$note_style\">" . $line['note'] . "</div>" .
+ $content;
}
- print "<title><![CDATA[" .
- htmlspecialchars($line["title"]) . "]]></title>";
+ $tpl->setVariable('ARTICLE_CONTENT', $content);
- print "<description><![CDATA[";
+ $tpl->setVariable('ARTICLE_UPDATED', date('c', strtotime($line["updated"])));
+ $tpl->setVariable('ARTICLE_AUTHOR', htmlspecialchars($line['author']));
- if ($line["note"]) {
- print "<div style='$note_style'>";
- print $line["note"];
- print "</div>";
- }
+ $tags = get_article_tags($link, $line["id"], $owner_uid);
- print sanitize_rss($link, $line["content_preview"], false, $owner_uid);
- print "]]></description>";
+ foreach ($tags as $tag) {
+ $tpl->setVariable('ARTICLE_CATEGORY', htmlspecialchars($tag));
+ $tpl->addBlock('category');
+ }
$enclosures = get_article_enclosures($link, $line["id"]);
$type = htmlspecialchars($e['content_type']);
$url = htmlspecialchars($e['content_url']);
$length = $e['duration'];
- print "<enclosure url=\"$url\" type=\"$type\" length=\"$length\"/>";
+
+ $tpl->setVariable('ARTICLE_ENCLOSURE_URL', $url);
+ $tpl->setVariable('ARTICLE_ENCLOSURE_TYPE', $type);
+ $tpl->setVariable('ARTICLE_ENCLOSURE_LENGTH', $length);
+
+ $tpl->addBlock('enclosure');
}
- print "</item>";
- }
+ $tpl->addBlock('entry');
+ }
+
+ $tmp = "";
- print "</channel></rss>";
+ $tpl->addBlock('feed');
+ $tpl->generateOutputToString($tmp);
+ print $tmp;
}
function getCategoryTitle($link, $cat_id) {
$res = trim($str); if (!$res) return '';
- if (get_pref($link, "STRIP_UNSAFE_TAGS", $owner) || $force_strip_tags) {
- $res = $purifier->purify($res);
- }
+// if (get_pref($link, "STRIP_UNSAFE_TAGS", $owner) || $force_strip_tags) {
+ $res = $purifier->purify($res);
+// }
if (get_pref($link, "STRIP_IMAGES", $owner)) {
$res = preg_replace('/<img[^>]+>/is', '', $res);
published = NOT published,last_read = NOW()
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
}
+
+ if (PUBSUBHUBBUB_HUB) {
+ $rss_link = get_self_url_prefix() .
+ "/backend.php?op=rss&id=-2&key=" .
+ get_feed_access_key($link, -2, false);
+
+ $p = new Publisher(PUBSUBHUBBUB_HUB);
+
+ $pubsub_result = $p->publish_update($rss_link);
+ }
}
function catchupArticlesById($link, $ids, $cmode, $owner_uid = false) {
$reply .= "<option value=\"emailArticle(false)\">".__('Forward by email').
"</option>";
+ if ($is_cat) $cat_q = "&is_cat=$is_cat";
+
$rss_link = htmlspecialchars(get_self_url_prefix() .
- "/backend.php?op=rss&id=$feed_id&is_cat=$is_cat&view_mode=$view_mode$search_q");
+ "/backend.php?op=rss&id=$feed_id$cat_q$search_q");
$reply .= "<option value=\"0\" disabled=\"1\">".__('Feed:')."</option>";
$search_q = "";
}
- // Adaptive doesn't really make any sense for generated feeds
- // All Articles is the default, so no need to insert it either
- if ($view_mode == "adaptive" || $view_mode == "all_articles")
- $view_mode = "";
- else
- $view_mode = "&view-mode=$view_mode";
-
$reply .= "
<a href=\"#\"
title=\"".__("View as RSS feed")."\"
class=\"hlTitle\"><span class='hlContent$hlc_suffix'>";
$reply['content'] .= "<a id=\"RTITLE-$id\"
href=\"" . htmlspecialchars($line["link"]) . "\"
- onclick=\"return false;\">" .
+ onclick=\"\">" .
$line["title"];
if (get_pref($link, 'SHOW_CONTENT_PREVIEW')) {
$tag = mb_strtolower($tag, 'utf-8');
- $tag = preg_replace('/[\"\+\>\<]/', "", $tag);
+ $tag = preg_replace('/[\'\"\+\>\<]/', "", $tag);
// $tag = str_replace('"', "", $tag);
// $tag = str_replace("+", " ", $tag);
function get_self_url_prefix() {
- $url_path = "";
+ /* $url_path = "";
if ($_SERVER['HTTPS'] != "on") {
$url_path = "http://";
$url_path .= $_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']);
- return $url_path;
+ return $url_path; */
+
+ return SELF_URL_PATH;
}
function opml_publish_url($link){
* @return string The Mozilla Firefox feed adding URL.
*/
function add_feed_url() {
- $url_path = ($_SERVER['HTTPS'] != "on" ? 'http://' : 'https://') . $_SERVER["HTTP_HOST"] . parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
- $url_path .= "?op=pref-feeds&quiet=1&subop=add&feed_url=%s";
+ //$url_path = ($_SERVER['HTTPS'] != "on" ? 'http://' : 'https://') . $_SERVER["HTTP_HOST"] . parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
+
+ $url_path = get_self_url_prefix() .
+ "/backend.php?op=pref-feeds&quiet=1&subop=add&feed_url=%s";
return $url_path;
} // function add_feed_url
$content = $tmhOAuth->response['response'];
+ define('MAGPIE_CACHE_ON', false);
+
$rss = new MagpieRSS($content, MAGPIE_OUTPUT_ENCODING,
MAGPIE_INPUT_ENCODING, MAGPIE_DETECT_ENCODING );