[Rt-commit] rt branch, librarize-send-dashboards, created. rt-3.9.4-533-gff5f357
Shawn Moore
sartak at bestpractical.com
Fri Nov 19 15:34:15 EST 2010
The branch, librarize-send-dashboards has been created
at ff5f3576e6e23b3ea2524841d0232579ff5a4da3 (commit)
- Log -----------------------------------------------------------------
commit ff5f3576e6e23b3ea2524841d0232579ff5a4da3
Author: Shawn M Moore <sartak at bestpractical.com>
Date: Fri Nov 19 15:33:33 2010 -0500
Librarize rt-email-dashboards
diff --git a/sbin/rt-email-dashboards.in b/lib/RT/Dashboard/Mailer.pm
similarity index 56%
copy from sbin/rt-email-dashboards.in
copy to lib/RT/Dashboard/Mailer.pm
index 0b7a6fc..1010162 100644
--- a/sbin/rt-email-dashboards.in
+++ b/lib/RT/Dashboard/Mailer.pm
@@ -1,4 +1,3 @@
-#!@PERL@
# BEGIN BPS TAGGED BLOCK {{{
#
# COPYRIGHT:
@@ -46,156 +45,132 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
+package RT::Dashboard::Mailer;
use strict;
use warnings;
-# fix lib paths, some may be relative
-BEGIN {
- require File::Spec;
- my @libs = ("@RT_LIB_PATH@", "@LOCAL_LIB_PATH@");
- my $bin_path;
-
- for my $lib (@libs) {
- unless ( File::Spec->file_name_is_absolute($lib) ) {
- unless ($bin_path) {
- if ( File::Spec->file_name_is_absolute(__FILE__) ) {
- $bin_path = ( File::Spec->splitpath(__FILE__) )[1];
- }
- else {
- require FindBin;
- no warnings "once";
- $bin_path = $FindBin::Bin;
- }
- }
- $lib = File::Spec->catfile( $bin_path, File::Spec->updir, $lib );
- }
- unshift @INC, $lib;
- }
-
-}
-
-# Read in the options
-my %opts;
-use Getopt::Long;
-GetOptions( \%opts,
- "help|h", "dryrun", "epoch=i", "all"
-);
-
-if ($opts{'help'}) {
- require Pod::Usage;
- print Pod::Usage::pod2usage(-verbose => 2);
- exit;
-}
-
-require RT;
-require RT::Interface::CLI;
-RT::Interface::CLI->import(qw{ CleanEnv loc });
-
-require HTML::Mason;
-require HTML::RewriteAttributes::Resources;
-require HTML::RewriteAttributes::Links;
-require MIME::Types;
-require POSIX;
-POSIX->import('tzset');
-require File::Temp;
-File::Temp->import('tempdir');
-
-# Clean out all the nasties from the environment
-CleanEnv();
-
-# Load the config file
-RT::LoadConfig();
-
-# Connect to the database and get RT::SystemUser and RT::Nobody loaded
-RT::Init();
-
-require RT::Interface::Web;
-require RT::Interface::Web::Handler;
-require RT::Dashboard;
-$HTML::Mason::Commands::r = RT::Dashboard::FakeRequest->new;
-
-no warnings 'once';
-
-my $now = $opts{epoch} || time;
-$RT::Logger->info("Using time " . scalar(localtime($now)) . " for dashboard generation");
-
-my $from = get_from();
-$RT::Logger->debug("Sending email from $from");
-
-# look through each user for her subscriptions
-my $Users = RT::Users->new(RT->SystemUser);
-$Users->LimitToPrivileged;
-
-while (defined(my $user = $Users->Next)) {
- if ($user->PrincipalObj->Disabled) {
- $RT::Logger->debug("Skipping over " . $user->Name . " due to having a disabled account.");
- next;
- }
+use HTML::Mason;
+use HTML::RewriteAttributes::Links;
+use HTML::RewriteAttributes::Resources;
+use MIME::Types;
+use POSIX 'tzset';
+use RT::Dashboard;
+use RT::Interface::Web::Handler;
+use RT::Interface::Web;
+use File::Temp 'tempdir';
+
+sub MailDashboards {
+ my $self = shift;
+ my %args = (
+ All => 0,
+ DryRun => 0,
+ Time => time,
+ @_,
+ );
- my ($hour, $dow, $dom) = hour_dow_dom_in($user->Timezone || RT->Config->Get('Timezone'));
- $hour .= ':00';
- $RT::Logger->debug("Checking ".$user->Name."'s subscriptions: hour $hour, dow $dow, dom $dom");
+ $RT::Logger->info("Using time " . $args{Time} . " for dashboard generation");
- my $currentuser = RT::CurrentUser->new;
- $currentuser->LoadByName($user->Name);
+ my $from = $self->GetFrom();
+ $RT::Logger->debug("Sending email from $from");
- # look through this user's subscriptions, are any supposed to be generated
- # right now?
- for my $subscription ($user->Attributes->Named('Subscription')) {
- my $counter = $subscription->SubValue('Counter') || 0;
+ local $HTML::Mason::Commands::r = RT::Dashboard::FakeRequest->new;
- if (!$opts{all}) {
- my $sub_frequency = $subscription->SubValue('Frequency');
- my $sub_hour = $subscription->SubValue('Hour');
- my $sub_dow = $subscription->SubValue('Dow');
- my $sub_dom = $subscription->SubValue('Dom');
- my $sub_fow = $subscription->SubValue('Fow');
+ # look through each user for her subscriptions
+ my $Users = RT::Users->new(RT->SystemUser);
+ $Users->LimitToPrivileged;
- $RT::Logger->debug("Checking against subscription with frequency $sub_frequency, hour $sub_hour, dow $sub_dow, dom $sub_dom, fow $sub_fow");
+ while (defined(my $user = $Users->Next)) {
+ if ($user->PrincipalObj->Disabled) {
+ $RT::Logger->debug("Skipping over " . $user->Name . " due to having a disabled account.");
+ next;
+ }
- next if $sub_frequency eq 'never';
+ my ($hour, $dow, $dom) = HourDowDomIn($args{Time}, $user->Timezone || RT->Config->Get('Timezone'));
+ $hour .= ':00';
+ $RT::Logger->debug("Checking ".$user->Name."'s subscriptions: hour $hour, dow $dow, dom $dom");
+
+ my $currentuser = RT::CurrentUser->new;
+ $currentuser->LoadByName($user->Name);
+
+ # look through this user's subscriptions, are any supposed to be generated
+ # right now?
+ for my $subscription ($user->Attributes->Named('Subscription')) {
+ my $counter = $subscription->SubValue('Counter') || 0;
+
+ if (!$args{All}) {
+ my $sub_frequency = $subscription->SubValue('Frequency');
+ my $sub_hour = $subscription->SubValue('Hour');
+ my $sub_dow = $subscription->SubValue('Dow');
+ my $sub_dom = $subscription->SubValue('Dom');
+ my $sub_fow = $subscription->SubValue('Fow');
+
+ $RT::Logger->debug("Checking against subscription with frequency $sub_frequency, hour $sub_hour, dow $sub_dow, dom $sub_dom, fow $sub_fow");
+
+ next if $sub_frequency eq 'never';
+
+ # correct hour?
+ next if $sub_hour ne $hour;
+
+ # if weekly, correct day of week?
+ if ( $sub_frequency eq 'weekly' ) {
+ next if $sub_frequency ne $dow;
+ my $fow = $sub_fow || 1;
+ if ( $counter % $fow ) {
+ $subscription->SetSubValues( Counter => $counter + 1 )
+ unless $args{DryRun};
+ next;
+ }
+ }
- # correct hour?
- next if $sub_hour ne $hour;
+ # if monthly, correct day of month?
+ elsif ($sub_frequency eq 'monthly') {
+ next if $sub_dom != $dom;
+ }
- # if weekly, correct day of week?
- if ( $sub_frequency eq 'weekly' ) {
- next if $sub_frequency ne $dow;
- my $fow = $sub_fow || 1;
- if ( $counter % $fow ) {
- $subscription->SetSubValues( Counter => $counter + 1 )
- unless $opts{'dryrun'};
- next;
+ elsif ($sub_frequency eq 'm-f') {
+ next if $dow eq 'Sunday' || $dow eq 'Saturday';
}
}
- # if monthly, correct day of month?
- elsif ($sub_frequency eq 'monthly') {
- next if $sub_dom != $dom;
+ my $email = $subscription->SubValue('Recipient')
+ || $user->EmailAddress;
+
+ eval {
+ $self->SendDashboard(
+ %args,
+ CurrentUser => $currentuser,
+ Email => $email,
+ Subscription => $subscription,
+ )
+ };
+ if ( $@ ) {
+ $RT::Logger->error("Caught exception: $@");
}
-
- elsif ($sub_frequency eq 'm-f') {
- next if $dow eq 'Sunday' || $dow eq 'Saturday';
+ else {
+ $subscription->SetSubValues(
+ Counter => $counter + 1 )
+ unless $args{DryRun};
}
}
-
- my $email = $subscription->SubValue('Recipient')
- || $user->EmailAddress;
-
- eval { send_dashboard($currentuser, $email, $subscription) };
- if ( $@ ) {
- $RT::Logger->error("Caught exception: $@");
- }
- else {
- $subscription->SetSubValues(
- Counter => $counter + 1 )
- unless $opts{'dryrun'};
- }
}
}
-sub send_dashboard {
- my ($currentuser, $email, $subscription) = @_;
+sub GetFrom {
+ RT->Config->Get('DashboardAddress') || RT->Config->Get('OwnerEmail')
+}
+
+sub SendDashboard {
+ my $self = shift;
+ my %args = (
+ CurrentUser => undef,
+ Email => undef,
+ Subscription => undef,
+ DryRun => 0,
+ @_,
+ );
+
+ my $currentuser = $args{CurrentUser};
+ my $subscription = $args{Subscription};
my $rows = $subscription->SubValue('Rows');
@@ -209,8 +184,8 @@ sub send_dashboard {
$RT::Logger->warning("Unable to load dashboard $DashboardId of subscription ".$subscription->Id." for user ".$currentuser->Name.": $msg");
my $ok = RT::Interface::Email::SendEmailUsingTemplate(
- From => $from,
- To => $email,
+ From => $args{From},
+ To => $args{Email},
Template => 'Error: Missing dashboard',
Arguments => {
SubscriptionObj => $subscription,
@@ -236,46 +211,66 @@ sub send_dashboard {
$RT::Logger->info('Generating dashboard "'.$dashboard->Name.'" for user "'.$currentuser->Name.'":');
- if ($opts{'dryrun'}) {
+ if ($args{DryRun}) {
print << "SUMMARY";
Dashboard: @{[ $dashboard->Name ]}
- User: @{[ $currentuser->Name ]} <$email>
+ User: @{[ $currentuser->Name ]} <$args{Email}>
SUMMARY
return;
}
$HTML::Mason::Commands::session{CurrentUser} = $currentuser;
- my $contents = run_component(
+ my $content = RunComponent(
'/Dashboards/Render.html',
id => $dashboard->Id,
Preview => 0,
);
for (@{ RT->Config->Get('EmailDashboardRemove') || [] }) {
- $contents =~ s/$_//g;
+ $content =~ s/$_//g;
}
- $RT::Logger->debug("Got ".length($contents)." characters of output.");
+ $RT::Logger->debug("Got ".length($content)." characters of output.");
- $contents = HTML::RewriteAttributes::Links->rewrite(
- $contents,
+ $content = HTML::RewriteAttributes::Links->rewrite(
+ $content,
RT->Config->Get('WebURL') . '/Dashboards/Render.html',
);
- email_dashboard($currentuser, $email, $dashboard, $subscription, $contents);
+ $self->EmailDashboard(
+ %args,
+ Dashboard => $dashboard,
+ Content => $content,
+ );
}
-sub email_dashboard {
- my ($currentuser, $email, $dashboard, $subscription, $content) = @_;
+sub EmailDashboard {
+ my $self = shift;
+ my %args = (
+ CurrentUser => undef,
+ Email => undef,
+ Dashboard => undef,
+ Subscription => undef,
+ Content => undef,
+ @_,
+ );
+
+ my $subscription = $args{Subscription};
+ my $dashboard = $args{Dashboard};
+ my $currentuser = $args{CurrentUser};
+ my $email = $args{Email};
my $subject = sprintf '[%s] ' . RT->Config->Get('DashboardSubject'),
RT->Config->Get('rtname'),
ucfirst($subscription->SubValue('Frequency')),
$dashboard->Name;
- my $entity = build_email($content, $from, $email, $subject);
+ my $entity = $self->BuildEmail(
+ %args,
+ Subject => $subject,
+ );
- $RT::Logger->info('Mailing dashboard "'.$dashboard->Name.'" to user '.$currentuser->Name.' <'.$email.'>');
+ $RT::Logger->info('Mailing dashboard "'.$dashboard->Name.'" to user '.$currentuser->Name." <$email>");
my $ok = RT::Interface::Email::SendEmail(
Entity => $entity,
@@ -287,19 +282,27 @@ sub email_dashboard {
$RT::Logger->error("Failed to email dashboard to user ".$currentuser->Name." <$email>");
}
-sub build_email {
- my ($content, $from, $to, $subject) = @_;
+sub BuildEmail {
+ my $self = shift;
+ my %args = (
+ Content => undef,
+ From => undef,
+ To => undef,
+ Subject => undef,
+ @_,
+ );
+
my @parts;
my %cid_of;
- $content = HTML::RewriteAttributes::Resources->rewrite($content, sub {
+ my $content = HTML::RewriteAttributes::Resources->rewrite($args{Content}, sub {
my $uri = shift;
# already attached this object
return "cid:$cid_of{$uri}" if $cid_of{$uri};
$cid_of{$uri} = time() . $$ . int(rand(1e6));
- my ($data, $filename, $mimetype, $encoding) = get_resource($uri);
+ my ($data, $filename, $mimetype, $encoding) = GetResource($uri);
# downgrade non-text strings, because all strings are utf8 by
# default, which is wrong for non-text strings.
@@ -321,16 +324,16 @@ sub build_email {
},
inline_css => sub {
my $uri = shift;
- my ($content) = get_resource($uri);
+ my ($content) = GetResource($uri);
return $content;
},
inline_imports => 1,
);
my $entity = MIME::Entity->build(
- From => $from,
- To => $to,
- Subject => $subject,
+ From => $args{From},
+ To => $args{To},
+ Subject => $args{Subject},
Type => "multipart/mixed",
);
@@ -348,16 +351,12 @@ sub build_email {
return $entity;
}
-sub get_from {
- RT->Config->Get('DashboardAddress') || RT->Config->Get('OwnerEmail')
-}
-
{
my $mason;
my $outbuf = '';
my $data_dir = '';
- sub mason {
+ sub _mason {
unless ($mason) {
$RT::Logger->debug("Creating Mason object.");
@@ -375,8 +374,8 @@ sub get_from {
return $mason;
}
- sub run_component {
- mason->exec(@_);
+ sub RunComponent {
+ _mason->exec(@_);
my $ret = $outbuf;
$outbuf = '';
return $ret;
@@ -386,9 +385,12 @@ sub get_from {
{
my %cache;
- sub hour_dow_dom_in {
- my $tz = shift;
- return @{$cache{$tz}} if exists $cache{$tz};
+ sub HourDowDomIn {
+ my $now = shift;
+ my $tz = shift;
+
+ my $key = "$now $tz";
+ return @{$cache{$key}} if exists $cache{$key};
my ($hour, $dow, $dom);
@@ -405,11 +407,11 @@ sub get_from {
if length($hour) == 1;
$dow = (qw/Sunday Monday Tuesday Wednesday Thursday Friday Saturday/)[$dow];
- return @{$cache{$tz}} = ($hour, $dow, $dom);
+ return @{$cache{$key}} = ($hour, $dow, $dom);
}
}
-sub get_resource {
+sub GetResource {
my $uri = URI->new(shift);
my ($content, $filename, $mimetype, $encoding);
@@ -449,7 +451,7 @@ sub get_resource {
}
$RT::Logger->debug("Running component '$path'");
- $content = run_component($path, %args);
+ $content = RunComponent($path, %args);
# guess at the filename from the component name
$filename = $1 if $path =~ m{^.*/(.*?)$};
@@ -474,77 +476,25 @@ sub get_resource {
return ($content, $filename, $mimetype, $encoding);
}
-package RT::Dashboard::FakeRequest;
-sub new { bless {}, shift }
-sub header_out { shift }
-sub headers_out { shift }
-sub content_type {
- my $self = shift;
- $self->{content_type} = shift if @_;
- return $self->{content_type};
-}
-sub path_info {
- my $self = shift;
- $self->{path_info} = shift if @_;
- return $self->{path_info};
-}
-
-=head1 NAME
-
-rt-email-dashboards - Send email dashboards
-
-=head1 SYNOPSIS
-
- rt-email-dashboards [options]
-
-=head1 DESCRIPTION
-
-This tool will send users email based on how they have subscribed to
-dashboards. A dashboard is a set of saved searches, the subscription controls
-how often that dashboard is sent and how it's displayed.
-Each subscription has an hour, and possibly day of week or day of month. These
-are taken to be in the user's timezone if available, UTC otherwise.
-
-=head1 SETUP
-
-You'll need to have cron run this script every hour. Here's an example crontab
-entry to do this.
-
- 0 * * * * @PERL@ /opt/rt3/local/sbin/rt-email-dashboards
-
-This will run the script every hour on the hour. This may need some further
-tweaking to be run as the correct user.
-
-=head1 OPTIONS
-
-This tool supports a few options. Most are for debugging.
-
-=over 8
-
-=item -h
-
-=item --help
-
-Display this documentation
-
-=item --dryrun
-
-Figure out which dashboards would be sent, but don't actually generate or email
-any of them
-
-=item --epoch SECONDS
-
-Instead of using the current time to figure out which dashboards should be
-sent, use SECONDS (usually since midnight Jan 1st, 1970, so C<1192216018> would
-be Oct 12 19:06:58 GMT 2007).
-
-=item --all
-
-Ignore subscription frequency when considering each dashboard (should only be
-used with --dryrun for testing and debugging)
+{
+ package RT::Dashboard::FakeRequest;
+ sub new { bless {}, shift }
+ sub header_out { shift }
+ sub headers_out { shift }
+ sub content_type {
+ my $self = shift;
+ $self->{content_type} = shift if @_;
+ return $self->{content_type};
+ }
+ sub path_info {
+ my $self = shift;
+ $self->{path_info} = shift if @_;
+ return $self->{path_info};
+ }
+}
-=back
+RT::Base->_ImportOverlays();
-=cut
+1;
diff --git a/sbin/rt-email-dashboards.in b/sbin/rt-email-dashboards.in
index 0b7a6fc..773f8b9 100644
--- a/sbin/rt-email-dashboards.in
+++ b/sbin/rt-email-dashboards.in
@@ -91,15 +91,6 @@ require RT;
require RT::Interface::CLI;
RT::Interface::CLI->import(qw{ CleanEnv loc });
-require HTML::Mason;
-require HTML::RewriteAttributes::Resources;
-require HTML::RewriteAttributes::Links;
-require MIME::Types;
-require POSIX;
-POSIX->import('tzset');
-require File::Temp;
-File::Temp->import('tempdir');
-
# Clean out all the nasties from the environment
CleanEnv();
@@ -109,385 +100,12 @@ RT::LoadConfig();
# Connect to the database and get RT::SystemUser and RT::Nobody loaded
RT::Init();
-require RT::Interface::Web;
-require RT::Interface::Web::Handler;
-require RT::Dashboard;
-$HTML::Mason::Commands::r = RT::Dashboard::FakeRequest->new;
-
-no warnings 'once';
-
-my $now = $opts{epoch} || time;
-$RT::Logger->info("Using time " . scalar(localtime($now)) . " for dashboard generation");
-
-my $from = get_from();
-$RT::Logger->debug("Sending email from $from");
-
-# look through each user for her subscriptions
-my $Users = RT::Users->new(RT->SystemUser);
-$Users->LimitToPrivileged;
-
-while (defined(my $user = $Users->Next)) {
- if ($user->PrincipalObj->Disabled) {
- $RT::Logger->debug("Skipping over " . $user->Name . " due to having a disabled account.");
- next;
- }
-
- my ($hour, $dow, $dom) = hour_dow_dom_in($user->Timezone || RT->Config->Get('Timezone'));
- $hour .= ':00';
- $RT::Logger->debug("Checking ".$user->Name."'s subscriptions: hour $hour, dow $dow, dom $dom");
-
- my $currentuser = RT::CurrentUser->new;
- $currentuser->LoadByName($user->Name);
-
- # look through this user's subscriptions, are any supposed to be generated
- # right now?
- for my $subscription ($user->Attributes->Named('Subscription')) {
- my $counter = $subscription->SubValue('Counter') || 0;
-
- if (!$opts{all}) {
- my $sub_frequency = $subscription->SubValue('Frequency');
- my $sub_hour = $subscription->SubValue('Hour');
- my $sub_dow = $subscription->SubValue('Dow');
- my $sub_dom = $subscription->SubValue('Dom');
- my $sub_fow = $subscription->SubValue('Fow');
-
- $RT::Logger->debug("Checking against subscription with frequency $sub_frequency, hour $sub_hour, dow $sub_dow, dom $sub_dom, fow $sub_fow");
-
- next if $sub_frequency eq 'never';
-
- # correct hour?
- next if $sub_hour ne $hour;
-
- # if weekly, correct day of week?
- if ( $sub_frequency eq 'weekly' ) {
- next if $sub_frequency ne $dow;
- my $fow = $sub_fow || 1;
- if ( $counter % $fow ) {
- $subscription->SetSubValues( Counter => $counter + 1 )
- unless $opts{'dryrun'};
- next;
- }
- }
-
- # if monthly, correct day of month?
- elsif ($sub_frequency eq 'monthly') {
- next if $sub_dom != $dom;
- }
-
- elsif ($sub_frequency eq 'm-f') {
- next if $dow eq 'Sunday' || $dow eq 'Saturday';
- }
- }
-
- my $email = $subscription->SubValue('Recipient')
- || $user->EmailAddress;
-
- eval { send_dashboard($currentuser, $email, $subscription) };
- if ( $@ ) {
- $RT::Logger->error("Caught exception: $@");
- }
- else {
- $subscription->SetSubValues(
- Counter => $counter + 1 )
- unless $opts{'dryrun'};
- }
- }
-}
-
-sub send_dashboard {
- my ($currentuser, $email, $subscription) = @_;
-
- my $rows = $subscription->SubValue('Rows');
-
- my $DashboardId = $subscription->SubValue('DashboardId');
-
- my $dashboard = RT::Dashboard->new($currentuser);
- my ($ok, $msg) = $dashboard->LoadById($DashboardId);
-
- # failed to load dashboard. perhaps it was deleted or it changed privacy
- if (!$ok) {
- $RT::Logger->warning("Unable to load dashboard $DashboardId of subscription ".$subscription->Id." for user ".$currentuser->Name.": $msg");
-
- my $ok = RT::Interface::Email::SendEmailUsingTemplate(
- From => $from,
- To => $email,
- Template => 'Error: Missing dashboard',
- Arguments => {
- SubscriptionObj => $subscription,
- },
- );
-
- # only delete the subscription if the email looks like it went through
- if ($ok) {
- my ($deleted, $msg) = $subscription->Delete();
- if ($deleted) {
- $RT::Logger->info("Deleted an obsolete subscription: $msg");
- }
- else {
- $RT::Logger->warning("Unable to delete an obsolete subscription: $msg");
- }
- }
- else {
- $RT::Logger->warning("Unable to notify ".$currentuser->Name." of an obsolete subscription");
- }
-
- return;
- }
-
- $RT::Logger->info('Generating dashboard "'.$dashboard->Name.'" for user "'.$currentuser->Name.'":');
-
- if ($opts{'dryrun'}) {
- print << "SUMMARY";
- Dashboard: @{[ $dashboard->Name ]}
- User: @{[ $currentuser->Name ]} <$email>
-SUMMARY
- return;
- }
-
- $HTML::Mason::Commands::session{CurrentUser} = $currentuser;
- my $contents = run_component(
- '/Dashboards/Render.html',
- id => $dashboard->Id,
- Preview => 0,
- );
-
- for (@{ RT->Config->Get('EmailDashboardRemove') || [] }) {
- $contents =~ s/$_//g;
- }
-
- $RT::Logger->debug("Got ".length($contents)." characters of output.");
-
- $contents = HTML::RewriteAttributes::Links->rewrite(
- $contents,
- RT->Config->Get('WebURL') . '/Dashboards/Render.html',
- );
-
- email_dashboard($currentuser, $email, $dashboard, $subscription, $contents);
-}
-
-sub email_dashboard {
- my ($currentuser, $email, $dashboard, $subscription, $content) = @_;
-
- my $subject = sprintf '[%s] ' . RT->Config->Get('DashboardSubject'),
- RT->Config->Get('rtname'),
- ucfirst($subscription->SubValue('Frequency')),
- $dashboard->Name;
-
- my $entity = build_email($content, $from, $email, $subject);
-
- $RT::Logger->info('Mailing dashboard "'.$dashboard->Name.'" to user '.$currentuser->Name.' <'.$email.'>');
-
- my $ok = RT::Interface::Email::SendEmail(
- Entity => $entity,
- );
-
- $RT::Logger->debug("Done sending dashboard to ".$currentuser->Name." <$email>")
- and return if $ok;
-
- $RT::Logger->error("Failed to email dashboard to user ".$currentuser->Name." <$email>");
-}
-
-sub build_email {
- my ($content, $from, $to, $subject) = @_;
- my @parts;
- my %cid_of;
-
- $content = HTML::RewriteAttributes::Resources->rewrite($content, sub {
- my $uri = shift;
-
- # already attached this object
- return "cid:$cid_of{$uri}" if $cid_of{$uri};
-
- $cid_of{$uri} = time() . $$ . int(rand(1e6));
- my ($data, $filename, $mimetype, $encoding) = get_resource($uri);
-
- # downgrade non-text strings, because all strings are utf8 by
- # default, which is wrong for non-text strings.
- if ( $mimetype !~ m{text/} ) {
- utf8::downgrade( $data, 1 ) or $RT::Logger->warning("downgrade $data failed");
- }
-
- push @parts, MIME::Entity->build(
- Top => 0,
- Data => $data,
- Type => $mimetype,
- Encoding => $encoding,
- Disposition => 'inline',
- Name => $filename,
- 'Content-Id' => $cid_of{$uri},
- );
-
- return "cid:$cid_of{$uri}";
- },
- inline_css => sub {
- my $uri = shift;
- my ($content) = get_resource($uri);
- return $content;
- },
- inline_imports => 1,
- );
-
- my $entity = MIME::Entity->build(
- From => $from,
- To => $to,
- Subject => $subject,
- Type => "multipart/mixed",
- );
-
- $entity->attach(
- Data => Encode::encode_utf8($content),
- Type => 'text/html',
- Charset => 'UTF-8',
- Disposition => 'inline',
- );
-
- for my $part (@parts) {
- $entity->add_part($part);
- }
-
- return $entity;
-}
-
-sub get_from {
- RT->Config->Get('DashboardAddress') || RT->Config->Get('OwnerEmail')
-}
-
-{
- my $mason;
- my $outbuf = '';
- my $data_dir = '';
-
- sub mason {
- unless ($mason) {
- $RT::Logger->debug("Creating Mason object.");
-
- # user may not have permissions on the data directory, so create a
- # new one
- $data_dir = tempdir(CLEANUP => 1);
-
- $mason = HTML::Mason::Interp->new(
- RT::Interface::Web::Handler->DefaultHandlerArgs,
- out_method => \$outbuf,
- autohandler_name => '', # disable forced login and more
- data_dir => $data_dir,
- );
- }
- return $mason;
- }
-
- sub run_component {
- mason->exec(@_);
- my $ret = $outbuf;
- $outbuf = '';
- return $ret;
- }
-}
-
-{
- my %cache;
-
- sub hour_dow_dom_in {
- my $tz = shift;
- return @{$cache{$tz}} if exists $cache{$tz};
-
- my ($hour, $dow, $dom);
-
- {
- local $ENV{'TZ'} = $tz;
- ## Using POSIX::tzset fixes a bug where the TZ environment variable
- ## is cached.
- tzset();
- (undef, undef, $hour, $dom, undef, undef, $dow) = localtime($now);
- }
- tzset(); # return back previous value
-
- $hour = "0$hour"
- if length($hour) == 1;
- $dow = (qw/Sunday Monday Tuesday Wednesday Thursday Friday Saturday/)[$dow];
-
- return @{$cache{$tz}} = ($hour, $dow, $dom);
- }
-}
-
-sub get_resource {
- my $uri = URI->new(shift);
- my ($content, $filename, $mimetype, $encoding);
-
- $RT::Logger->info("Getting resource $uri");
-
- # strip out the equivalent of WebURL, so we start at the correct /
- my $path = $uri->path;
- my $webpath = RT->Config->Get('WebPath');
- $path =~ s/^\Q$webpath//;
-
- # add a leading / if needed
- $path = "/$path"
- unless $path =~ m{^/};
-
- $HTML::Mason::Commands::r->path_info($path);
-
- # grab the query arguments
- my %args;
- for (split /&/, ($uri->query||'')) {
- my ($k, $v) = /^(.*?)=(.*)$/
- or die "Unable to parse query parameter '$_'";
-
- for ($k, $v) { s/%(..)/chr hex $1/ge }
-
- # no value yet, simple key=value
- if (!exists $args{$k}) {
- $args{$k} = $v;
- }
- # already have key=value, need to upgrade it to key=[value1, value2]
- elsif (!ref($args{$k})) {
- $args{$k} = [$args{$k}, $v];
- }
- # already key=[value1, value2], just add the new value
- else {
- push @{ $args{$k} }, $v;
- }
- }
-
- $RT::Logger->debug("Running component '$path'");
- $content = run_component($path, %args);
-
- # guess at the filename from the component name
- $filename = $1 if $path =~ m{^.*/(.*?)$};
-
- # the rest of this was taken from Email::MIME::CreateHTML::Resolver::LWP
- ($mimetype, $encoding) = MIME::Types::by_suffix($filename);
-
- my $content_type = $HTML::Mason::Commands::r->content_type;
- if ($content_type) {
- $mimetype = $content_type;
-
- # strip down to just a MIME type
- $mimetype = $1 if $mimetype =~ /(\S+);\s*charset=(.*)$/;
- }
-
- #If all else fails then some conservative and general-purpose defaults are:
- $mimetype ||= 'application/octet-stream';
- $encoding ||= 'base64';
-
- $RT::Logger->debug("Resource $uri: length=".length($content)." filename='$filename' mimetype='$mimetype', encoding='$encoding'");
-
- return ($content, $filename, $mimetype, $encoding);
-}
-
-package RT::Dashboard::FakeRequest;
-sub new { bless {}, shift }
-sub header_out { shift }
-sub headers_out { shift }
-sub content_type {
- my $self = shift;
- $self->{content_type} = shift if @_;
- return $self->{content_type};
-}
-sub path_info {
- my $self = shift;
- $self->{path_info} = shift if @_;
- return $self->{path_info};
-}
+require RT::Dashboard::Mailer;
+RT::Dashboard::Mailer->MailDashboards(
+ All => $opts{all},
+ DryRun => $opts{dryrun},
+ Time => ($opts{epoch} || time),
+);
=head1 NAME
-----------------------------------------------------------------------
More information about the Rt-commit
mailing list