From 8980bebcb38eaaca934141b1828e243609577a51 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 4 Nov 2009 17:32:17 -0800 Subject: Add a table and DB_DataObject class for storing cloud subscriptions --- plugins/RSSCloud/RSSCloudPlugin.php | 33 ++++-- plugins/RSSCloud/RSSCloudRequestNotify.php | 167 ++++++++++++++++------------- plugins/RSSCloud/RSSCloudSubscription.php | 82 ++++++++++++++ 3 files changed, 200 insertions(+), 82 deletions(-) create mode 100644 plugins/RSSCloud/RSSCloudSubscription.php diff --git a/plugins/RSSCloud/RSSCloudPlugin.php b/plugins/RSSCloud/RSSCloudPlugin.php index 816739889..10f81b8dd 100644 --- a/plugins/RSSCloud/RSSCloudPlugin.php +++ b/plugins/RSSCloud/RSSCloudPlugin.php @@ -95,14 +95,15 @@ class RSSCloudPlugin extends Plugin { switch ($cls) { - + case 'RSSCloudSubscription': + include_once(INSTALLDIR . '/plugins/RSSCloud/RSSCloudSubscription.php'); + return false; case 'RSSCloudNotifier': - require_once(INSTALLDIR . '/plugins/RSSCloud/RSSCloudNotifier.php'); + include_once(INSTALLDIR . '/plugins/RSSCloud/RSSCloudNotifier.php'); return false; case 'RSSCloudRequestNotifyAction': case 'LoggingAggregatorAction': - common_debug(mb_substr($cls, 0, -6) . '.php'); - require_once(INSTALLDIR . '/plugins/RSSCloud/' . mb_substr($cls, 0, -6) . '.php'); + include_once(INSTALLDIR . '/plugins/RSSCloud/' . mb_substr($cls, 0, -6) . '.php'); return false; default: return true; @@ -155,10 +156,10 @@ class RSSCloudPlugin extends Plugin function onUnqueueHandleNotice(&$notice, $queue) { if (($queue == 'rsscloud') && ($this->_isLocal($notice))) { - + // broadcast the notice here common_debug('broadcasting rssCloud bound notice ' . $notice->id); - + return false; } return true; @@ -176,6 +177,24 @@ class RSSCloudPlugin extends Plugin return ($notice->is_local == Notice::LOCAL_PUBLIC || $notice->is_local == Notice::LOCAL_NONPUBLIC); } - + + + function onCheckSchema() { + $schema = Schema::get(); + $schema->ensureTable('rsscloud_subscription', + array(new ColumnDef('subscribed', 'integer', + null, false, 'PRI'), + new ColumnDef('url', 'varchar', + '255', false, 'PRI'), + new ColumnDef('failures', 'integer', + null, false, 'MUL'), + new ColumnDef('created', 'datetime', + null, false), + new ColumnDef('modified', 'timestamp') + ) + ); + return true; + } + } diff --git a/plugins/RSSCloud/RSSCloudRequestNotify.php b/plugins/RSSCloud/RSSCloudRequestNotify.php index 48bd3fb27..8b5deb136 100644 --- a/plugins/RSSCloud/RSSCloudRequestNotify.php +++ b/plugins/RSSCloud/RSSCloudRequestNotify.php @@ -51,10 +51,10 @@ class RSSCloudRequestNotifyAction extends Action $this->path = $this->arg('path'); $this->protocol = $this->arg('protocol'); $this->procedure = $this->arg('notifyProcedure'); + $this->domain = $this->arg('domain'); + $this->feeds = $this->getFeeds(); - $this->subscriber_url = 'http://' . $this->ip . ':' . $this->port . $this->path; - return true; } @@ -102,70 +102,93 @@ class RSSCloudRequestNotifyAction extends Action return; } - $endpoint = $ip . ':' . $port . $path; + // We have to validate everything before saving anything. + // We only return one success or failure no matter how + // many feeds the subscriber is trying to subscribe to foreach ($this->feeds as $feed) { - $this->saveSubscription($feed); + + if (!$this->validateFeed($feed)) { + $msg = 'Feed subscription failed - Not a valid feed.'; + $this->showResult(false, $msg); + return; + } + + if (!$this->testNotificationHandler($feed)) { + $msg = 'Feed subscription failed - ' . + 'notification handler doesn\'t respond correctly.'; + $this->showResult(false, $msg); + return; + } + } + foreach ($this->feeds as $feed) { + $this->saveSubscription($feed); + } + // XXX: What to do about deleting stale subscriptions? 25 hours seems harsh. // WordPress doesn't ever remove subscriptions. $msg = 'Thanks for the registration. It worked. When the feed(s) update(s) we\'ll notify you. ' . ' Don\'t forget to re-register after 24 hours, your subscription will expire in 25.'; - $this->showResult(true, $msg); + $this->showResult(true, $msg); } - function getFeeds() + function validateFeed($feed) { - $feeds = array(); - - foreach ($this->args as $key => $feed ) { - if (preg_match('|url\d+|', $key)) { + $user = $this->userFromFeed($feed); - if ($this->testFeed($feed)) { - $feeds[] = $feed; - } else { - $msg = 'RSSCloud Plugin - ' . $this->ip . ' tried to subscribe ' . - 'to a non-existent feed: ' . $feed; - common_log(LOG_WARN, $msg); - } - } + if (empty($user)) { + return false; } - return $feeds; + return true; } - function testNotificationHandler($feed) - { - $notifier = new RSSCloudNotifier(); - return $notifier->postUpdate($endpoint, $feed); - } - // returns valid user or false - function testFeed($feed) + function getFeeds() { - $user = $this->userFromFeed($feed); + $feeds = array(); + + while (list($key, $feed) = each ($this->args)) { + if (preg_match('/^url\d*$/', $key)) { + $feeds[] = $feed; + } + } - if (!empty($user)) { + return $feeds; + } - common_debug("Valid feed: $feed"); + function testNotificationHandler($feed) + { + common_debug("RSSCloudPlugin - testNotificationHandler()"); + + $notifier = new RSSCloudNotifier(); + + if (isset($this->domain)) { + + //get + + $this->url = 'http://' . $this->domain . ':' . $this->port . '/' . $this->path; + + common_debug('domain set need to send challenge'); + + } else { + + //post + + $this->url = 'http://' . $this->ip . ':' . $this->port . '/' . $this->path; + + //return $notifier->postUpdate($endpoint, $feed); - // OK, so this is a valid profile feed url, now let's see if the - // other system reponds to our notifications before we - // add the sub... + } - if ($this->testNotificationHandler($feed)) { - return true; - } - } + return true; - return false; } - // this actually does the validating and figuring out the - // user, which it returns function userFromFeed($feed) { // We only do profile feeds @@ -185,45 +208,39 @@ class RSSCloudRequestNotifyAction extends Action function saveSubscription($feed) { - // check to see if we already have a profile for this subscriber - - $other = Remote_profile::staticGet('uri', $this->subscriber_url); - - if ($other === false) { - $other->saveProfile(); - } - - $user = userFromFeed($feed); - - $result = subs_subscribe_to($user, $other); - - if ($result != true) { - $msg = "RSSPlugin - got '$result' trying to subscribe " . - "$this->subscriber_url to $user->nickname" . "'s profile feed."; - common_log(LOG_WARN, $msg); + $user = $this->userFromFeed($feed); + + common_debug('user = ' . $user->id); + + $sub = RSSCloudSubscription::getSubscription($user->id, $this->url); + + if ($sub) { + common_debug("already subscribed to that!"); } else { - $msg = 'RSSCloud plugin - subscribe: ' . $this->subscriber_url . - ' subscribed to ' . $feed; - - common_log(LOG_INFO, $msg); + common_debug('No feed for user ' . $user->id . ' notify: ' . $this->url); } - } - - function saveProfile() - { - common_debug("Saving remote profile for $this->subscriber_url"); - - // XXX: We need to add a field to Remote_profile to indicate the kind - // of remote profile? i.e: OMB, RSSCloud, PuSH, Twitter - - $remote = new Remote_profile(); - $remote->uri = $this->subscriber_url; - $remote->postnoticeurl = $this->subscriber_url; - $remote->created = DB_DataObject_Cast::dateTime(); - - if (!$remote->insert()) { - throw new Exception(_('RSSCloud plugin - Error inserting remote profile!')); + + common_debug('RSSPlugin - saveSubscription'); + // turn debugging high + DB_DataObject::debugLevel(5); + + $sub = new RSSCloudSubscription(); + + $sub->subscribed = $user->id; + $sub->url = $this->url; + $sub->created = common_sql_now(); + + // auto timestamp doesn't seem to work for me + + $sub->modified = common_sql_now(); + + if (!$sub->insert()) { + common_log_db_error($sub, 'INSERT', __FILE__); + return false; } + DB_DataObject::debugLevel(); + + return true; } function showResult($success, $msg) diff --git a/plugins/RSSCloud/RSSCloudSubscription.php b/plugins/RSSCloud/RSSCloudSubscription.php new file mode 100644 index 000000000..0b102e2e6 --- /dev/null +++ b/plugins/RSSCloud/RSSCloudSubscription.php @@ -0,0 +1,82 @@ +. + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { + exit(1); +} + +/** + * Table Definition for rsscloud_subscription + */ + +require_once INSTALLDIR . '/classes/Memcached_DataObject.php'; + +class RSSCloudSubscription extends Memcached_DataObject { + + var $__table='rsscloud_subscription'; // table name + var $subscribed; // int primary key user id + var $url; // string primary key + var $failures; // int + var $created; // datestamp() + var $modified; // timestamp() not_null default_CURRENT_TIMESTAMP + + function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('DataObjects_Grp',$k,$v); } + + function table() + { + global $_DB_DATAOBJECT; + $dbtype = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['phptype']; + + $cols = array( + 'subscribed' => DB_DATAOBJECT_INT, + 'url' => DB_DATAOBJECT_STR, + 'failures' => DB_DATAOBJECT_INT, + 'created' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME, + 'modified' => ($dbtype == 'mysql') ? + DB_DATAOBJECT_MYSQLTIMESTAMP : + DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + ); + + + // common_debug(var_export($cols, true)); + return $cols; + } + + function keys() + { + return array('subscribed', 'url'); + } + + static function getSubscription($subscribed, $url) + { + $sub = new RSSCloudSubscription(); + $sub->whereAdd("subscribed = $subscribed"); + $sub->whereAdd("url = $url"); + $sub->limit(1); + + if ($sub->find()) { + $sub->fetch(); + return $sub; + } + + return false; + } + +} +?> \ No newline at end of file -- cgit v1.2.3-54-g00ecf