Browse Source

implement pubsubhubbub subscriber (update schema)

Andrew Dolgov 13 years ago
parent
commit
5ab9791f34

+ 39 - 2
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);

+ 0 - 4
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.

+ 63 - 9
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 );
 

+ 2 - 7
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 "<rpc-reply>";
-			print "<message>UPDATE_COUNTERS</message>";
-			print "</rpc-reply>";
-
 			return;
 		} */
 

+ 2 - 2
sanity_config.php

@@ -1,3 +1,3 @@
-<?php # This file has been generated at:  Fri Apr 1 09:34:52 MSD 2011
+<?php # This file has been generated at:  Fri Apr 1 13:36:01 MSD 2011
 define('GENERATED_CONFIG_CHECK', 22);
-$requred_defines = array( 'DB_TYPE', 'DB_HOST', 'DB_USER', 'DB_NAME', 'DB_PASS', 'MAGPIE_FETCH_TIME_OUT', 'MAGPIE_CACHE_DIR', 'MAGPIE_CACHE_AGE', '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', 'ISCONFIGURED', 'PUBSUBHUBBUB_HUB', 'CONFIG_VERSION'); ?>
+$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'); ?>

+ 1 - 0
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),

+ 1 - 0
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);

+ 5 - 0
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;

+ 5 - 0
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;