[RSSCloud] Update schema definition

This commit is contained in:
Alexei Sorokin 2020-08-11 18:23:45 +03:00 committed by Diogo Peralta Cordeiro
parent e051572f84
commit 1095475645
3 changed files with 152 additions and 143 deletions

View File

@ -1,35 +1,37 @@
This plugin enables RSSCloud (http://rsscloud.org/) publishing and subscription
This plugin enables RSSCloud (http://rsscloud.co/) publishing and subscription
handling for RSS 2.0 profile feeds (i.e:
http://SITE/PATH/api/statuses/user_timeline/USERNAME.rss). When the plugin is
enabled, StatusNet acts as both the publisher and hub ('writer' and 'cloud' in
RSSCloud parlance), but only for local StatusNet feeds. It's not possible to use
enabled, GNU social acts as both the publisher and hub ('writer' and 'cloud' in
RSSCloud parlance), but only for local GNU social feeds. It's not possible to use
it as a general purpose hub -- for instance you can't subscribe and get updates
to a Wordpress feed from StatusNet using this plugin.
to a Wordpress feed from GNU social using this plugin.
To use the plugin, add the following to your config.php:
addPlugin('RSSCloud');
```php
addPlugin('RSSCloud');
```
Enabling the plugin will add a <cloud> element to your RSS 2.0 profile feeds
that looks like this:
<cloud domain="SITE" port="80" path="/main/rsscloud/request_notify"
registerProcedure="" protocol="http-post"/>
```
<cloud domain="SITE" port="80" path="/main/rsscloud/request_notify"
registerProcedure="" protocol="http-post"/>
```
Aggregators may subscribe by sending a proper REST RSSCloud subscription request
(the optional 'domain' parameter with challenge is supported). Subscribing
aggregators will be notified ('pinged') when users they have subscribed to post
new notices. Currently, REST is the only protocol supported for notifications.
Deamon
------
## Daemon
There's also a daemon for offline processing of queued notices with RSSCloud
destinations, which will start automatically if/when you run
scripts/startdaemons.sh.
Notes
-----
## Notes
- Again, only RSS 2.0 profile feeds may be subscribed to, and they have to be
the ones with user names in them, like:
@ -39,8 +41,7 @@ Notes
- The plugin includes a dummy LoggingAggregator class that can be used for
end-to-end testing. You probably don't want to mess with it.
TODO
----
## TODO
- Figure out why the RSSCloudSubcription can't ->delete() or ->update()
- Support pinging via XML-RPC and SOAP

View File

@ -1,35 +1,30 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* StatusNet, the distributed open-source microblogging tool
*
* Plugin to support RSSCloud
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Plugin
* @package StatusNet
* @package GNUsocial
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
if (!defined('STATUSNET')) {
exit(1);
}
defined('GNUSOCIAL') || die();
define('RSSCLOUDPLUGIN_VERSION', '0.1.0');
@ -39,8 +34,7 @@ define('RSSCLOUDPLUGIN_VERSION', '0.1.0');
* @category Plugin
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class RSSCloudPlugin extends Plugin
{
@ -49,7 +43,7 @@ class RSSCloudPlugin extends Plugin
*
* @return void
*/
function __construct()
public function __construct()
{
parent::__construct();
}
@ -60,7 +54,7 @@ class RSSCloudPlugin extends Plugin
*
* @return void
*/
function onInitializePlugin()
public function onInitializePlugin(): void
{
$this->domain = common_config('rsscloud', 'domain');
$this->port = common_config('rsscloud', 'port');
@ -98,19 +92,22 @@ class RSSCloudPlugin extends Plugin
*
* Hook for RouterInitialized event.
*
* @param Mapper $m URL parser and mapper
*
* @return boolean hook return
* @param URLMapper $m URL parser and mapper
* @return bool hook return
*/
function onRouterInitialized($m)
public function onRouterInitialized(URLMapper $m): bool
{
$m->connect('/main/rsscloud/request_notify',
['action' => 'RSSCloudRequestNotify']);
$m->connect(
'main/rsscloud/request_notify',
['action' => 'RSSCloudRequestNotify']
);
// XXX: This is just for end-to-end testing. Uncomment if you need to pretend
// to be a cloud hub for some reason.
//$m->connect('/main/rsscloud/notify',
// array('action' => 'LoggingAggregator'));
//$m->connect(
// 'main/rsscloud/notify',
// ['action' => 'LoggingAggregator']
//);
return true;
}
@ -120,18 +117,18 @@ class RSSCloudPlugin extends Plugin
* element is started).
*
* @param Action $action the ApiAction
*
* @return void
*/
function onStartApiRss($action)
public function onStartApiRss(Action $action): void
{
if (get_class($action) == 'ApiTimelineUserAction') {
$attrs = array('domain' => $this->domain,
$attrs = [
'domain' => $this->domain,
'port' => $this->port,
'path' => $this->path,
'registerProcedure' => $this->funct,
'protocol' => $this->protocol);
'protocol' => $this->protocol,
];
// Dipping into XMLWriter to avoid a full end element (</cloud>).
@ -149,12 +146,13 @@ class RSSCloudPlugin extends Plugin
*
* @param Notice $notice the notice
* @param array &$transports the list of transports (queues)
*
* @return boolean hook return
* @return bool hook return
*/
function onStartEnqueueNotice($notice, &$transports)
{
public function onStartEnqueueNotice(
Notice $notice,
array &$transports
): bool {
if ($notice->isLocal()) {
array_push($transports, 'rsscloud');
}
@ -165,23 +163,16 @@ class RSSCloudPlugin extends Plugin
* Create the rsscloud_subscription table if it's not
* already in the DB
*
* @return boolean hook return
* @return bool hook return
*/
function onCheckSchema()
public function onCheckSchema(): bool
{
$schema = Schema::get();
$schema->ensureTable('rsscloud_subscription',
array(
'fields' => array(
'subscribed' => array('type' => 'int', 'not null' => true),
'url' => array('type' => 'varchar', 'length' => '191', 'not null' => true),
'failures' => array('type' => 'int', 'not null' => true, 'default' => 0),
'created' => array('type' => 'datetime', 'not null' => true),
'modified' => array('type' => 'timestamp', 'not null' => true),
),
'primary key' => array('subscribed', 'url'),
));
$schema->ensureTable(
'rsscloud_subscription',
RSSCloudSubscription::schemaDef()
);
return true;
}
@ -189,26 +180,50 @@ class RSSCloudPlugin extends Plugin
* Register RSSCloud notice queue handler
*
* @param QueueManager $manager
*
* @return boolean hook return
* @return bool hook return
*/
function onEndInitializeQueueManager($manager)
public function onEndInitializeQueueManager(QueueManager $manager): bool
{
$manager->connect('rsscloud', 'RSSCloudQueueHandler');
return true;
}
/**
* Ensure that subscriptions for a user are deleted
* when that user gets deleted.
*
* @param User $user
* @param array &$related list of related tables
*
* @return bool hook result
*/
public function onUserDeleteRelated(User $user, array &$related): bool
{
$sub = new RSSCloudSubscription();
$sub->subscribed = $user->id;
if ($sub->find()) {
while ($sub->fetch()) {
$sub->delete();
}
}
$sub->free();
return true;
}
public function onPluginVersion(array &$versions): bool
{
$versions[] = array('name' => 'RSSCloud',
$versions[] = [
'name' => 'RSSCloud',
'version' => RSSCLOUDPLUGIN_VERSION,
'author' => 'Zach Copley',
'homepage' => GNUSOCIAL_ENGINE_REPO_URL . 'tree/master/plugins/RSSCloud',
'rawdescription' =>
// TRANS: Plugin description.
_m('The RSSCloud plugin enables your StatusNet instance to publish ' .
'real-time updates for profile RSS feeds using the ' .
'<a href="http://rsscloud.org/">RSSCloud protocol</a>.'));
_m('The RSSCloud plugin enables your GNU social instance to '
. 'publish real-time updates for profile RSS feeds using the '
. '<a href="http://rsscloud.co/">rssCloud protocol</a>.'),
];
return true;
}

View File

@ -1,71 +1,64 @@
<?php
/*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008, 2009, StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Table Definition for rsscloud_subscription
*
* @category Plugin
* @package GNUsocial
* @author Zach Copley <zach@status.net>
* @copyright 2008, 2009 StatusNet, Inc.
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
defined('GNUSOCIAL') || die();
class RSSCloudSubscription extends Memcached_DataObject {
class RSSCloudSubscription extends Managed_DataObject
{
public $__table='rsscloud_subscription'; // table name
public $subscribed; // int primary key user id
public $url; // string primary key
public $failures; // int
public $created; // datestamp()
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
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
static function getKV($k,$v=NULL) { return DB_DataObject::staticGet('DataObjects_Grp',$k,$v); }
function table()
public static function schemaDef(): array
{
$db = $this->getDatabaseConnection();
$dbtype = $db->phptype;
$cols = array('subscribed' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
'url' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
'failures' => DB_DATAOBJECT_INT,
'created' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL,
'modified' => ($dbtype == 'mysql' || $dbtype == 'mysqli') ?
DB_DATAOBJECT_MYSQLTIMESTAMP + DB_DATAOBJECT_NOTNULL :
DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME
);
return $cols;
return [
'fields' => [
'subscribed' => ['type' => 'int', 'not null' => true],
'url' => ['type' => 'varchar', 'length' => '191', 'not null' => true],
'failures' => ['type' => 'int', 'not null' => true, 'default' => 0],
'created' => ['type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'],
'modified' => ['type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'],
],
'primary key' => ['subscribed', 'url'],
'foreign keys' => [
'rsscloud_subscription_subscribed_fkey' => ['user', ['subscribed' => 'id']],
],
];
}
function keys()
{
return array('subscribed' => 'N', 'url' => 'N');
}
static function getSubscription($subscribed, $url)
{
public static function getSubscription(
int $subscribed,
string $url
): ?self {
$sub = new RSSCloudSubscription();
$sub->whereAdd("subscribed = $subscribed");
$sub->whereAdd("url = '$url'");
$sub->whereAdd("subscribed = {$subscribed}");
$sub->whereAdd("url = '{$sub->escape($url)}'");
$sub->limit(1);
if ($sub->find()) {
@ -73,6 +66,6 @@ class RSSCloudSubscription extends Memcached_DataObject {
return $sub;
}
return false;
return null;
}
}