From 5ab9791f34d395104b4857b0979ae9aa5c138878 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Fri, 1 Apr 2011 13:39:58 +0400 Subject: [PATCH] implement pubsubhubbub subscriber (update schema) --- backend.php | 41 +++++++++++++++++++- config.php-dist | 4 -- functions.php | 72 ++++++++++++++++++++++++++++++----- modules/backend-rpc.php | 9 +---- sanity_config.php | 4 +- schema/ttrss_schema_mysql.sql | 1 + schema/ttrss_schema_pgsql.sql | 1 + schema/versions/mysql/83.sql | 5 +++ schema/versions/pgsql/83.sql | 5 +++ 9 files changed, 118 insertions(+), 24 deletions(-) diff --git a/backend.php b/backend.php index fd5ad6e7..d62b2db2 100644 --- a/backend.php +++ b/backend.php @@ -61,7 +61,8 @@ } if (!($_SESSION["uid"] && validate_session($link)) && $op != "globalUpdateFeeds" && - $op != "rss" && $op != "getUnread" && $op != "getProfiles") { + $op != "rss" && $op != "getUnread" && $op != "getProfiles" && + $op != "pubsub") { header("Content-Type: text/plain"); print json_encode(array("error" => array("code" => 6))); @@ -524,8 +525,44 @@ } break; - } // Select action according to $op value. + case "pubsub": + $mode = db_escape_string($_REQUEST['hub_mode']); + $feed_id = db_escape_string($_REQUEST['id']); + $feed_url = db_escape_string($_REQUEST['hub_topic']); + + // TODO: implement hub_verifytoken checking + + $result = db_query($link, "SELECT feed_url FROM ttrss_feeds + WHERE id = '$feed_id'"); + + $check_feed_url = db_fetch_result($result, 0, "feed_url"); + + if ($check_feed_url && ($check_feed_url == $feed_url || !$feed_url)) { + if ($mode == "subscribe") { + + db_query($link, "UPDATE ttrss_feeds SET pubsub_state = 2 + WHERE id = '$feed_id'"); + + echo $_REQUEST['hub_challenge']; + } else if ($mode == "unsubscribe") { + + db_query($link, "UPDATE ttrss_feeds SET pubsub_state = 0 + WHERE id = '$feed_id'"); + + echo $_REQUEST['hub_challenge']; + } else if (!$mode) { + // Received update ping, schedule feed update. + + update_rss_feed($link, $feed_id, true, true); + + } + } else { + header('HTTP/1.0 404 Not Found'); + } + + break; + } // Select action according to $op value. // We close the connection to database. db_close($link); diff --git a/config.php-dist b/config.php-dist index e9ea0a67..8b01aeb8 100644 --- a/config.php-dist +++ b/config.php-dist @@ -18,10 +18,6 @@ define('MAGPIE_CACHE_DIR', 'cache/magpie'); // Local cache directory for RSS feeds - define('MAGPIE_CACHE_AGE', 60*30); - // How long to store cached RSS objects? In seconds. - // Defaults to 30 minutes - define('ICONS_DIR', "icons"); define('ICONS_URL', "icons"); // Local and URL path to the directory, where feed favicons are stored. diff --git a/functions.php b/functions.php index 1e843dd1..5adf46cd 100644 --- a/functions.php +++ b/functions.php @@ -99,7 +99,6 @@ //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); @@ -111,6 +110,7 @@ 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(); @@ -471,7 +471,7 @@ } } - function update_rss_feed($link, $feed, $ignore_daemon = false) { + function update_rss_feed($link, $feed, $ignore_daemon = false, $no_cache = false) { global $memcache; @@ -483,14 +483,14 @@ 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; @@ -518,7 +518,8 @@ $result = db_query($link, "SELECT id,update_interval,auth_login, feed_url,auth_pass,cache_images,update_method,last_updated, - mark_unread_on_update, owner_uid, update_on_checksum_change + mark_unread_on_update, owner_uid, update_on_checksum_change, + pubsub_state FROM ttrss_feeds WHERE id = '$feed'"); } @@ -537,6 +538,7 @@ 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'"); @@ -601,7 +603,11 @@ 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)) { @@ -628,7 +634,9 @@ 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); } @@ -728,7 +736,7 @@ $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); } @@ -758,6 +766,50 @@ return; // no articles } + if (PUBSUBHUBBUB_HUB && $pubsub_state != 2) { + + $feed_hub_url = false; + if ($use_simplepie) { + $links = $rss->get_links('hub'); + + 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"]; + } + } + } + } else { + $feed_hub_url = $rss->channel['link_hub']; + } + } + + if ($feed_hub_url) { + $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..."); } @@ -7073,6 +7125,8 @@ $content = $tmhOAuth->response['response']; + define('MAGPIE_CACHE_ON', false); + $rss = new MagpieRSS($content, MAGPIE_OUTPUT_ENCODING, MAGPIE_INPUT_ENCODING, MAGPIE_DETECT_ENCODING ); diff --git a/modules/backend-rpc.php b/modules/backend-rpc.php index abb04ab4..4f2ba252 100644 --- a/modules/backend-rpc.php +++ b/modules/backend-rpc.php @@ -228,15 +228,10 @@ return; } -/* if ($subop == "updateFeed") { + // Silent + /* if ($subop == "update") { $feed_id = db_escape_string($_REQUEST["feed"]); - update_rss_feed($link, $feed_id); - - print ""; - print "UPDATE_COUNTERS"; - print ""; - return; } */ diff --git a/sanity_config.php b/sanity_config.php index fb51ffa0..22598d3d 100644 --- a/sanity_config.php +++ b/sanity_config.php @@ -1,3 +1,3 @@ - +$requred_defines = array( 'DB_TYPE', 'DB_HOST', 'DB_USER', 'DB_NAME', 'DB_PASS', 'MAGPIE_FETCH_TIME_OUT', 'MAGPIE_CACHE_DIR', 'ICONS_DIR', 'ICONS_URL', 'SINGLE_USER_MODE', 'TMP_DIRECTORY', 'ENABLE_UPDATE_DAEMON', 'DAEMON_SLEEP_INTERVAL', 'DATABASE_BACKED_SESSIONS', 'SESSION_CHECK_ADDRESS', 'SESSION_COOKIE_LIFETIME', 'SESSION_EXPIRE_TIME', 'DAEMON_UPDATE_LOGIN_LIMIT', 'CHECK_FOR_NEW_VERSION', 'DIGEST_ENABLE', 'DIGEST_EMAIL_LIMIT', 'DAEMON_SENDS_DIGESTS', 'MYSQL_CHARSET', 'DEFAULT_UPDATE_METHOD', 'SIMPLEPIE_CACHE_DIR', 'SIMPLEPIE_CACHE_IMAGES', 'COUNTERS_MAX_AGE', 'DIGEST_FROM_NAME', 'DIGEST_FROM_ADDRESS', 'DIGEST_SUBJECT', 'DIGEST_SMTP_HOST', 'DIGEST_SMTP_LOGIN', 'DIGEST_SMTP_PASSWORD', 'DAEMON_FEED_LIMIT', 'ALLOW_REMOTE_USER_AUTH', 'AUTO_LOGIN', 'LOCK_DIRECTORY', 'ENABLE_GZIP_OUTPUT', 'PHP_EXECUTABLE', 'ENABLE_REGISTRATION', 'REG_NOTIFY_ADDRESS', 'REG_MAX_USERS', 'FEEDBACK_URL', 'FORCE_ARTICLE_PURGE', 'SPHINX_ENABLED', 'SPHINX_INDEX', 'ENABLE_TWEET_BUTTON', 'CONSUMER_KEY', 'CONSUMER_SECRET', 'PUBSUBHUBBUB_HUB', 'ISCONFIGURED', 'CONFIG_VERSION'); ?> diff --git a/schema/ttrss_schema_mysql.sql b/schema/ttrss_schema_mysql.sql index 46e08dea..4b528f94 100644 --- a/schema/ttrss_schema_mysql.sql +++ b/schema/ttrss_schema_mysql.sql @@ -125,6 +125,7 @@ create table ttrss_feeds (id integer not null auto_increment primary key, mark_unread_on_update boolean not null default false, update_on_checksum_change boolean not null default false, strip_images boolean not null default false, + pubsub_state integer not null default 0, index(owner_uid), foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE, index(cat_id), diff --git a/schema/ttrss_schema_pgsql.sql b/schema/ttrss_schema_pgsql.sql index 8d87663d..bb870703 100644 --- a/schema/ttrss_schema_pgsql.sql +++ b/schema/ttrss_schema_pgsql.sql @@ -88,6 +88,7 @@ create table ttrss_feeds (id serial not null primary key, mark_unread_on_update boolean not null default false, update_on_checksum_change boolean not null default false, strip_images boolean not null default false, + pubsub_state integer not null default 0, auth_pass_encrypted boolean not null default false); create index ttrss_feeds_owner_uid_index on ttrss_feeds(owner_uid); diff --git a/schema/versions/mysql/83.sql b/schema/versions/mysql/83.sql index b8609153..6457539a 100644 --- a/schema/versions/mysql/83.sql +++ b/schema/versions/mysql/83.sql @@ -19,6 +19,11 @@ DELETE FROM ttrss_user_prefs WHERE pref_name IN ('HIDE_FEEDLIST', 'SYNC_COUNTERS DELETE FROM ttrss_prefs WHERE pref_name IN ('HIDE_FEEDLIST', 'SYNC_COUNTERS', 'ENABLE_LABELS', 'ENABLE_SEARCH_TOOLBAR', 'ENABLE_FEED_ICONS', 'ENABLE_OFFLINE_READING', 'EXTENDED_FEEDLIST', 'OPEN_LINKS_IN_NEW_WINDOW', 'ENABLE_FLASH_PLAYER', 'HEADLINES_SMART_DATE', 'MARK_UNREAD_ON_UPDATE', 'UPDATE_POST_ON_CHECKSUM_CHANGE'); +alter table ttrss_feeds add column pubsub_state integer; +update ttrss_feeds set pubsub_state = 0; +alter table ttrss_feeds change pubsub_state pubsub_state integer not null; +alter table ttrss_feeds alter column pubsub_state set default 0; + update ttrss_version set schema_version = 83; commit; diff --git a/schema/versions/pgsql/83.sql b/schema/versions/pgsql/83.sql index 12ffb173..c622f813 100644 --- a/schema/versions/pgsql/83.sql +++ b/schema/versions/pgsql/83.sql @@ -19,6 +19,11 @@ DELETE FROM ttrss_user_prefs WHERE pref_name IN ('HIDE_FEEDLIST', 'SYNC_COUNTERS DELETE FROM ttrss_prefs WHERE pref_name IN ('HIDE_FEEDLIST', 'SYNC_COUNTERS', 'ENABLE_LABELS', 'ENABLE_SEARCH_TOOLBAR', 'ENABLE_FEED_ICONS', 'ENABLE_OFFLINE_READING', 'EXTENDED_FEEDLIST', 'OPEN_LINKS_IN_NEW_WINDOW', 'ENABLE_FLASH_PLAYER', 'HEADLINES_SMART_DATE', 'MARK_UNREAD_ON_UPDATE', 'UPDATE_POST_ON_CHECKSUM_CHANGE'); +alter table ttrss_feeds add column pubsub_state integer; +update ttrss_feeds set pubsub_state = 0; +alter table ttrss_feeds alter column pubsub_state set not null; +alter table ttrss_feeds alter column pubsub_state set default 0; + update ttrss_version set schema_version = 83; commit; -- 2.39.5