JavaScript and other changes to make realtime_channel management work

This commit is contained in:
Evan Prodromou 2011-07-13 16:10:08 -04:00
parent 3c3ab128b3
commit 58ea000485
6 changed files with 88 additions and 24 deletions

View File

@ -93,16 +93,24 @@ class RealtimePlugin extends Plugin
*/
function onRouterInitialized($m)
{
// Discovery actions
$m->connect('main/channel/:channel_key/keepalive',
array('action' => 'keepalivechannel'));
$m->connect('main/channel/:channel_key/close',
array('action' => 'closechannel'));
$m->connect('main/channel/:channelkey/keepalive',
array('action' => 'keepalivechannel'),
array('channelkey' => '[a-z0-9]{32}'));
$m->connect('main/channel/:channelkey/close',
array('action' => 'closechannel'),
array('channelkey' => '[a-z0-9]{32}'));
return true;
}
function onEndShowScripts($action)
{
$timeline = $this->_getTimeline($action);
$channel = $this->_getChannel($action);
if (empty($channel)) {
return true;
}
$timeline = $this->_pathToChannel(array($channel->channel_key));
// If there's not a timeline on this page,
// just return true
@ -137,12 +145,14 @@ class RealtimePlugin extends Plugin
}
else {
$pluginPath = common_path('plugins/Realtime/');
$realtimeUI = ' RealtimeUpdate.initActions("'.$url.'", "'.$timeline.'", "'. $pluginPath .'");';
$keepalive = common_local_url('keepalivechannel', array('channelkey' => $channel->channel_key));
$close = common_local_url('closechannel', array('channelkey' => $channel->channel_key));
$realtimeUI = ' RealtimeUpdate.initActions("'.$url.'", "'.$timeline.'", "'. $pluginPath .'", "'.$keepalive.'", "'.$close.'"); ';
}
$script = ' $(document).ready(function() { '.
$realtimeUI.
$this->_updateInitialize($timeline, $user_id).
$this->_updateInitialize($timeline, $user_id).
'}); ';
$action->inlineScript($script);
@ -431,7 +441,18 @@ class RealtimePlugin extends Plugin
return '';
}
function _getTimeline($action)
{
$channel = $this->_getChannel($action);
if (empty($channel)) {
return null;
}
return $this->_pathToChannel(array($channel->channel_key));
}
function _getChannel($action)
{
$timeline = null;
$arg1 = null;
@ -480,12 +501,8 @@ class RealtimePlugin extends Plugin
$action_name,
$arg1,
$arg2);
if (!empty($channel)) {
$timeline = $this->_pathToChannel(array($channel->channel_key));
}
return $timeline;
return $channel;
}
function onStartReadWriteTables(&$alwaysRW, &$rwdb)

View File

@ -58,6 +58,7 @@ class Realtime_channel extends Managed_DataObject
public $arg1; // argument
public $arg2; // argument, usually null
public $channel_key; // 128-bit shared secret key
public $audience; // listener count
public $created; // created date
public $modified; // modified date
@ -117,6 +118,10 @@ class Realtime_channel extends Managed_DataObject
'length' => 32,
'not null' => true,
'description' => 'shared secret key for this channel'),
'audience' => array('type' => 'integer',
'not null' => true,
'default' => 0,
'description' => 'reference count'),
'created' => array('type' => 'datetime',
'not null' => true,
'description' => 'date this record was created'),
@ -144,6 +149,7 @@ class Realtime_channel extends Managed_DataObject
$channel->action = $action;
$channel->arg1 = $arg1;
$channel->arg2 = $arg2;
$channel->audience = 1;
$channel->channel_key = common_good_rand(16); // 128-bit key, 32 hex chars
@ -230,18 +236,40 @@ class Realtime_channel extends Managed_DataObject
}
if ($channel->find(true)) {
$channel->touch();
$channel->increment();
return $channel;
} else {
return null;
}
}
function increment()
{
// XXX: race
$orig = clone($this);
$this->audience++;
$this->modified = common_sql_now();
$this->update($orig);
}
function touch()
{
// Touch it!
// XXX: race
$orig = clone($this);
$this->modified = common_sql_now();
$this->update($orig);
}
}
function decrement()
{
// XXX: race
if ($this->audience == 1) {
$this->delete();
} else {
$orig = clone($this);
$this->audience--;
$this->modified = common_sql_now();
$this->update($orig);
}
}
}

View File

@ -66,7 +66,7 @@ class ClosechannelAction extends Action
throw new ClientException(_m('You have to POST it.'));
}
$this->channelKey = $this->trimmed('channel_key');
$this->channelKey = $this->trimmed('channelkey');
if (empty($this->channelKey)) {
throw new ClientException(_m('No channel key argument.'));
@ -91,7 +91,7 @@ class ClosechannelAction extends Action
function handle($argarray=null)
{
$this->channel->delete();
$this->channel->decrement();
header('HTTP/1.1 204 No Content');

View File

@ -66,7 +66,7 @@ class KeepalivechannelAction extends Action
throw new ClientException(_m('You have to POST it.'));
}
$this->channelKey = $this->trimmed('channel_key');
$this->channelKey = $this->trimmed('channelkey');
if (empty($this->channelKey)) {
throw new ClientException(_m('No channel key argument.'));

View File

@ -1,6 +1,6 @@
/*
* StatusNet - a distributed open-source microblogging tool
* Copyright (C) 2008, StatusNet, Inc.
* Copyright (C) 2009-2011, StatusNet, Inc.
*
* Add a notice encoded as JSON into the current timeline
*
@ -21,7 +21,7 @@
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Sarven Capadisli <csarven@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009-2011 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/
*/
@ -45,6 +45,8 @@
RealtimeUpdate = {
_userid: 0,
_showurl: '',
_keepaliveurl: '',
_closeurl: '',
_updatecounter: 0,
_maxnotices: 50,
_windowhasfocus: true,
@ -390,11 +392,28 @@ RealtimeUpdate = {
*
* @access private
*/
initActions: function(url, timeline, path)
initActions: function(url, timeline, path, keepaliveurl, closeurl)
{
$('#notices_primary').prepend('<ul id="realtime_actions"><li id="realtime_playpause"></li><li id="realtime_timeline"></li></ul>');
RealtimeUpdate._pluginPath = path;
RealtimeUpdate._keepaliveurl = keepaliveurl;
RealtimeUpdate._closeurl = closeurl;
// On unload, let the server know we're no longer listening
$(window).unload(function() {
$.ajax({
type: 'POST',
url: RealtimeUpdate._closeurl});
});
setInterval(function() {
$.ajax({
type: 'POST',
url: RealtimeUpdate._keepaliveurl});
}, 15 * 60 * 1000 ); // every 15 min; timeout in 30 min
RealtimeUpdate.initPlayPause();
RealtimeUpdate.initAddPopup(url, timeline, RealtimeUpdate._pluginPath);

File diff suppressed because one or more lines are too long