Complete email summary sending system
Added the necessary classes to send email summaries. First, added a script to run on a daily basis. Second, added a queue handler for sending email summaries for users, and another to queue summaries for all users on the site. Fixed up the email_summary_status table to store the last-sent notice id, rather than a datetime (since we don't support 'since' parameters anymore). Finally, made the plugin class load the right modules when needed.
This commit is contained in:
parent
9003769609
commit
797059340e
|
@ -63,7 +63,7 @@ class EmailSummaryPlugin extends Plugin
|
||||||
false, 'PRI'),
|
false, 'PRI'),
|
||||||
new ColumnDef('send_summary', 'tinyint', null,
|
new ColumnDef('send_summary', 'tinyint', null,
|
||||||
false, null, 1),
|
false, null, 1),
|
||||||
new ColumnDef('last_summary', 'datetime', null,
|
new ColumnDef('last_summary_id', 'integer', null,
|
||||||
true),
|
true),
|
||||||
new ColumnDef('created', 'datetime', null,
|
new ColumnDef('created', 'datetime', null,
|
||||||
false),
|
false),
|
||||||
|
@ -89,6 +89,10 @@ class EmailSummaryPlugin extends Plugin
|
||||||
|
|
||||||
switch ($cls)
|
switch ($cls)
|
||||||
{
|
{
|
||||||
|
case 'SiteEmailSummaryHandler':
|
||||||
|
case 'UserEmailSummaryHandler':
|
||||||
|
include_once $dir . '/'.strtolower($cls).'.php';
|
||||||
|
return false;
|
||||||
case 'Email_summary_status':
|
case 'Email_summary_status':
|
||||||
include_once $dir . '/'.$cls.'.php';
|
include_once $dir . '/'.$cls.'.php';
|
||||||
return false;
|
return false;
|
||||||
|
@ -116,4 +120,19 @@ class EmailSummaryPlugin extends Plugin
|
||||||
_m('Send an email summary of the inbox to users.'));
|
_m('Send an email summary of the inbox to users.'));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register our queue handlers
|
||||||
|
*
|
||||||
|
* @param QueueManager $qm Current queue manager
|
||||||
|
*
|
||||||
|
* @return boolean hook value
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onEndInitializeQueueManager($qm)
|
||||||
|
{
|
||||||
|
$qm->connect('sitesum', 'SiteEmailSummaryHandler');
|
||||||
|
$qm->connect('usersum', 'UserEmailSummaryHandler');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,9 +52,9 @@ class Email_summary_status extends Memcached_DataObject
|
||||||
public $__table = 'email_summary_status'; // table name
|
public $__table = 'email_summary_status'; // table name
|
||||||
public $user_id; // int(4) primary_key not_null
|
public $user_id; // int(4) primary_key not_null
|
||||||
public $send_summary; // tinyint not_null
|
public $send_summary; // tinyint not_null
|
||||||
public $last_summary; // int(4) primary_key not_null
|
public $last_summary_id; // int(4) null
|
||||||
public $created; // int(4) primary_key not_null
|
public $created; // datetime not_null
|
||||||
public $modified; // int(4) primary_key not_null
|
public $modified; // datetime not_null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an instance by key
|
* Get an instance by key
|
||||||
|
@ -83,9 +83,9 @@ class Email_summary_status extends Memcached_DataObject
|
||||||
{
|
{
|
||||||
return array('user_id' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
return array('user_id' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
||||||
'send_summary' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
'send_summary' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
||||||
'last_summary' => DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME,
|
'last_summary_id' => DB_DATAOBJECT_INT,
|
||||||
'created' => DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME,
|
'created' => DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL,
|
||||||
'modified' => DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME);
|
'modified' => DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,14 +154,14 @@ class Email_summary_status extends Memcached_DataObject
|
||||||
* @return Email_summary_status instance for this user, with count already incremented.
|
* @return Email_summary_status instance for this user, with count already incremented.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static function getLastSummary($user_id)
|
static function getLastSummaryID($user_id)
|
||||||
{
|
{
|
||||||
$ess = Email_summary_status::staticGet('user_id', $user_id);
|
$ess = Email_summary_status::staticGet('user_id', $user_id);
|
||||||
|
|
||||||
if (!empty($ess)) {
|
if (!empty($ess)) {
|
||||||
return $ess->last_summary;
|
return $ess->last_summary_id;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
47
plugins/EmailSummary/sendemailsummary.php
Normal file
47
plugins/EmailSummary/sendemailsummary.php
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* StatusNet - a distributed open-source microblogging tool
|
||||||
|
* Copyright (C) 2010, 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../..'));
|
||||||
|
|
||||||
|
$shortoptions = 'i:n:a';
|
||||||
|
$longoptions = array('id=', 'nickname=', 'all');
|
||||||
|
|
||||||
|
$helptext = <<<END_OF_SENDEMAILSUMMARY_HELP
|
||||||
|
sendemailsummary.php [options]
|
||||||
|
Send an email summary of the inbox to users
|
||||||
|
|
||||||
|
-i --id ID of user to send summary to
|
||||||
|
-n --nickname nickname of the user to send summary to
|
||||||
|
-a --all send summary to all users
|
||||||
|
|
||||||
|
END_OF_SENDEMAILSUMMARY_HELP;
|
||||||
|
|
||||||
|
require_once INSTALLDIR.'/scripts/commandline.inc';
|
||||||
|
|
||||||
|
$qm = QueueManager::get();
|
||||||
|
|
||||||
|
// enqueue summary for user or all users
|
||||||
|
|
||||||
|
try {
|
||||||
|
$user = getUser();
|
||||||
|
$qm->enqueue($user->id, 'usersum');
|
||||||
|
} catch (NoUserArgumentException $nuae) {
|
||||||
|
$qm->enqueue(null, 'sitesum');
|
||||||
|
}
|
96
plugins/EmailSummary/siteemailsummaryhandler.php
Normal file
96
plugins/EmailSummary/siteemailsummaryhandler.php
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* StatusNet - the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Handler for queue items of type 'sitesum', sends email summaries
|
||||||
|
* to all users on the site.
|
||||||
|
*
|
||||||
|
* 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 Sample
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @copyright 2010 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Handler for queue items of type 'sitesum', sends email summaries
|
||||||
|
* to all users on the site.
|
||||||
|
*
|
||||||
|
* @category Email
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @copyright 2010 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
class SiteEmailSummaryHandler extends QueueHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return transport keyword which identifies items this queue handler
|
||||||
|
* services; must be defined for all subclasses.
|
||||||
|
*
|
||||||
|
* Must be 8 characters or less to fit in the queue_item database.
|
||||||
|
* ex "email", "jabber", "sms", "irc", ...
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
|
||||||
|
function transport()
|
||||||
|
{
|
||||||
|
return 'sitesum';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the site
|
||||||
|
*
|
||||||
|
* @param mixed $object
|
||||||
|
* @return boolean true on success, false on failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($object)
|
||||||
|
{
|
||||||
|
$qm = QueueManager::get();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Enqueue a summary for all users
|
||||||
|
|
||||||
|
$user = new User();
|
||||||
|
$user->find();
|
||||||
|
|
||||||
|
while ($user->fetch()) {
|
||||||
|
try {
|
||||||
|
$qm->enqueue($user->id, 'usersum');
|
||||||
|
} catch (Exception $e) {
|
||||||
|
common_log(LOG_WARNING, $e->getMessage());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
common_log(LOG_WARNING, $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
172
plugins/EmailSummary/useremailsummaryhandler.php
Normal file
172
plugins/EmailSummary/useremailsummaryhandler.php
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet - the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Handler for queue items of type 'usersum', sends an email summaries
|
||||||
|
* to a particular user.
|
||||||
|
*
|
||||||
|
* 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 Sample
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @copyright 2010 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for queue items of type 'usersum', sends an email summaries
|
||||||
|
* to a particular user.
|
||||||
|
*
|
||||||
|
* @category Email
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @copyright 2010 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
class UserEmailSummaryHandler extends QueueHandler
|
||||||
|
{
|
||||||
|
// Maximum number of notices to include by default. This is probably too much.
|
||||||
|
|
||||||
|
const MAX_NOTICES = 200;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return transport keyword which identifies items this queue handler
|
||||||
|
* services; must be defined for all subclasses.
|
||||||
|
*
|
||||||
|
* Must be 8 characters or less to fit in the queue_item database.
|
||||||
|
* ex "email", "jabber", "sms", "irc", ...
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
|
||||||
|
function transport()
|
||||||
|
{
|
||||||
|
return 'sitesum';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a summary email to the user
|
||||||
|
*
|
||||||
|
* @param mixed $object
|
||||||
|
* @return boolean true on success, false on failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($user_id)
|
||||||
|
{
|
||||||
|
// Skip if they've asked not to get summaries
|
||||||
|
|
||||||
|
$ess = Email_summary_status::staticGet('user_id', $user_id);
|
||||||
|
|
||||||
|
if (!empty($ess) && !$ess->send_summary) {
|
||||||
|
common_log(LOG_INFO, sprintf('Not sending email summary for user %s by request.', $user_id));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$since_id = null;
|
||||||
|
|
||||||
|
if (!empty($ess)) {
|
||||||
|
$since_id = $ess->last_summary_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = User::staticGet('id', $user_id);
|
||||||
|
|
||||||
|
if (empty($user)) {
|
||||||
|
common_log(LOG_INFO, sprintf('Not sending email summary for user %s; no such user.', $user_id));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($user->email)) {
|
||||||
|
common_log(LOG_INFO, sprintf('Not sending email summary for user %s; no email address.', $user_id));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile = $user->getProfile();
|
||||||
|
|
||||||
|
if (empty($profile)) {
|
||||||
|
common_log(LOG_WARNING, sprintf('Not sending email summary for user %s; no profile.', $user_id));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$notice = $user->ownFriendsTimeline(0, self::MAX_NOTICES, $since_id);
|
||||||
|
|
||||||
|
if (empty($notice) || $notice->N == 0) {
|
||||||
|
common_log(LOG_WARNING, sprintf('Not sending email summary for user %s; no notices.', $user_id));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX: This is risky fingerpoken in der objektvars, but I didn't feel like
|
||||||
|
// figuring out a better way. -ESP
|
||||||
|
|
||||||
|
$new_top = null;
|
||||||
|
|
||||||
|
if ($notice instanceof ArrayWrapper) {
|
||||||
|
$new_top = $notice->_items[0]->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$out = new XMLStringer();
|
||||||
|
|
||||||
|
$out->raw(sprintf(_('<p>Recent updates from %1s for %2s:</p>'),
|
||||||
|
common_config('site', 'name'),
|
||||||
|
$profile->getBestName()));
|
||||||
|
|
||||||
|
$nl = new NoticeList($notice, $out);
|
||||||
|
|
||||||
|
// Outputs to the string
|
||||||
|
|
||||||
|
$nl->show();
|
||||||
|
|
||||||
|
$out->raw(sprintf(_('<p><a href="%1s">change your email settings for %2s</a></p>'),
|
||||||
|
common_local_url('emailsettings'),
|
||||||
|
common_config('site', 'name')));
|
||||||
|
|
||||||
|
$body = $out->getString();
|
||||||
|
|
||||||
|
// FIXME: do something for people who don't like HTML email
|
||||||
|
|
||||||
|
mail_to_user($user, _('Updates from your network'), $body,
|
||||||
|
array('Content-Type', 'text/html; charset=UTF-8'));
|
||||||
|
|
||||||
|
if (empty($ess)) {
|
||||||
|
|
||||||
|
$ess = new Email_summary_status();
|
||||||
|
|
||||||
|
$ess->user_id = $user_id;
|
||||||
|
$ess->created = common_sql_now();
|
||||||
|
$ess->last_summary_id = $new_top;
|
||||||
|
$ess->modified = common_sql_now();
|
||||||
|
|
||||||
|
$ess->insert();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$orig = clone($ess);
|
||||||
|
|
||||||
|
$ess->last_summary_id = $new_top;
|
||||||
|
$ess->modified = common_sql_now();
|
||||||
|
|
||||||
|
$ess->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user