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'),
|
||||
new ColumnDef('send_summary', 'tinyint', null,
|
||||
false, null, 1),
|
||||
new ColumnDef('last_summary', 'datetime', null,
|
||||
new ColumnDef('last_summary_id', 'integer', null,
|
||||
true),
|
||||
new ColumnDef('created', 'datetime', null,
|
||||
false),
|
||||
|
@ -89,6 +89,10 @@ class EmailSummaryPlugin extends Plugin
|
|||
|
||||
switch ($cls)
|
||||
{
|
||||
case 'SiteEmailSummaryHandler':
|
||||
case 'UserEmailSummaryHandler':
|
||||
include_once $dir . '/'.strtolower($cls).'.php';
|
||||
return false;
|
||||
case 'Email_summary_status':
|
||||
include_once $dir . '/'.$cls.'.php';
|
||||
return false;
|
||||
|
@ -116,4 +120,19 @@ class EmailSummaryPlugin extends Plugin
|
|||
_m('Send an email summary of the inbox to users.'));
|
||||
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 $user_id; // int(4) primary_key not_null
|
||||
public $send_summary; // tinyint not_null
|
||||
public $last_summary; // int(4) primary_key not_null
|
||||
public $created; // int(4) primary_key not_null
|
||||
public $modified; // int(4) primary_key not_null
|
||||
public $last_summary_id; // int(4) null
|
||||
public $created; // datetime not_null
|
||||
public $modified; // datetime not_null
|
||||
|
||||
/**
|
||||
* 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,
|
||||
'send_summary' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
||||
'last_summary' => DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME,
|
||||
'created' => DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME,
|
||||
'modified' => DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME);
|
||||
'last_summary_id' => DB_DATAOBJECT_INT,
|
||||
'created' => DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL,
|
||||
'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.
|
||||
*/
|
||||
|
||||
static function getLastSummary($user_id)
|
||||
static function getLastSummaryID($user_id)
|
||||
{
|
||||
$ess = Email_summary_status::staticGet('user_id', $user_id);
|
||||
|
||||
if (!empty($ess)) {
|
||||
return $ess->last_summary;
|
||||
return $ess->last_summary_id;
|
||||
} 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