CPAN-Testers-WWW-Reports-Mailer

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

        - moved DEBUG configuration to configuration file
        - took out application configuration from MANIFEST and replaced it with
          an example one, so as not to clobbered any settings from the real one
          when installed.
        - fixed InsertDistPrefs SQL string.

0.03    2008-11-06
        - port bulk of script code into Mailer module.

0.02    2008-11-06
        - prefs_distributions table extended to include distribution version,
          platform, perl version and patches preferences.
        - code added to cpanstats-mailer (v0.02) to include new preferences.
        - redesigned tables so that login and activity are held in the author
          table, and all distribution preferences are held in the distribution
          table, where defaults are where distribution == '-'.
        - redesigned new author insertions
        - implemented a simple phrasebook lookup for SQL queries.

0.01    2008-09-08
        - initial release

MANIFEST  view on Meta::CPAN

bin/cpanreps-mailer
Changes
examples/cpanprefs-mailer.sh
examples/settings-example.ini
lib/CPAN/Testers/WWW/Reports/Mailer.pm
LICENSE
Makefile.PL
MANIFEST
META.json
META.yml
README
sponsors.json
t/01base.t
t/05setup-db.t
t/20attributes.t
t/21init.t
t/22help.t
t/23logging.t
t/30counts.t
t/31lastid.t
t/32get_author.t
t/33prefs.t
t/34get_sponsor.t
t/60setup-db.t
t/61daily.t
t/62daily.t
t/63daily.t
t/64daily.t
t/65daily.t
t/66daily.t
t/67reports.t
t/70setup-db.t
t/71daily.t
t/89cleanup.t
t/90podtest.t
t/91podcover.t
t/94metatest.t
t/95changedate.t
t/96metatest.t
t/data/01mailrc.txt
t/data/05data-db-articles.txt
t/data/05data-db-cpanstats.txt
t/data/05data-db-prefs_authors.txt
t/data/05data-db-prefs_distributions.txt
t/data/05data-db-uploads.txt
t/data/60data-db-cpanstats.txt
t/data/60data-db-ixlatest.txt
t/data/60data-db-uploads.txt
t/data/61daily.eml
t/data/62daily.eml
t/data/63daily.eml
t/data/64daily.eml
t/data/67reports.eml
t/data/70data-db-cpanstats.txt

bin/cpanreps-mailer  view on Meta::CPAN

my $VERSION = '0.06';

#----------------------------------------------------------------------------

=head1 NAME

cpanstats-mailer - script to mail authors links to reports of their modules

=head1 SYNOPSIS

  perl cpanstats-mailer --config=prefs.ini

=head1 DESCRIPTION

Collates report links for each author, based on the preferences set for each
author, and mails them a single report. This script is expected to run daily
and in tests produces only 40% of the previous mail volumes to authors.

=cut

# -------------------------------------

examples/settings-example.ini  view on Meta::CPAN

[CPANPREFS]
driver=mysql
database=cpanprefs
dbhost=localhost
dbuser=username
dbpass=password

[SETTINGS]
verbose=0
nomail=1
logfile=logs/cpanreps.log
logclean=1

lib/CPAN/Testers/WWW/Reports/Mailer.pm  view on Meta::CPAN

        { 'id' =>  9, 'value' => "September", },
        { 'id' => 10, 'value' => "October",   },
        { 'id' => 11, 'value' => "November",  },
        { 'id' => 12, 'value' => "December"   },
);

our %phrasebook = (
    'LastReport'        => "SELECT MAX(id) FROM cpanstats.cpanstats",
    'GetEarliest'       => "SELECT id FROM cpanstats.cpanstats WHERE fulldate > ? ORDER BY id LIMIT 1",

    'FindAuthorType'    => "SELECT pauseid FROM prefs_distributions WHERE report = ?",

    'GetReports'        => "SELECT id,guid,dist,version,platform,perl,state FROM cpanstats.cpanstats WHERE id > ? AND state IN ('pass','fail','na','unknown') ORDER BY id",
    'GetReports2'       => "SELECT c.id,c.guid,c.dist,c.version,c.platform,c.perl,c.state FROM cpanstats.cpanstats AS c INNER JOIN cpanstats.ixlatest AS x ON x.dist=c.dist WHERE c.id > ? AND c.state IN ('pass','fail','na','unknown') AND author IN (%s...
    'GetReportCount'    => "SELECT id FROM cpanstats.cpanstats WHERE platform=? AND perl=? AND state=? AND id < ? AND dist=? AND version=? LIMIT 2",
    'GetLatestDistVers' => "SELECT version FROM cpanstats.uploads WHERE dist=? ORDER BY released DESC LIMIT 1",
    'GetAuthor'         => "SELECT author FROM cpanstats.uploads WHERE dist=? AND version=? LIMIT 1",
    'GetAuthors'        => "SELECT author,dist,version FROM cpanstats.uploads",

    'GetAuthorPrefs'    => "SELECT * FROM prefs_authors WHERE pauseid=?",
    'GetDefaultPrefs'   => "SELECT * FROM prefs_authors AS a INNER JOIN prefs_distributions AS d ON d.pauseid=a.pauseid AND d.distribution='-' WHERE a.pauseid=?",
    'GetDistPrefs'      => "SELECT * FROM prefs_distributions WHERE pauseid=? AND distribution=?",
    'InsertAuthorLogin' => 'INSERT INTO prefs_authors (active,lastlogin,pauseid) VALUES (1,?,?)',
    'InsertDistPrefs'   => "INSERT INTO prefs_distributions (pauseid,distribution,ignored,report,grade,tuple,version,patches,perl,platform) VALUES (?,?,0,1,'FAIL','FIRST','LATEST',0,'ALL','ALL')",

    'GetArticle'        => "SELECT * FROM articles.articles WHERE id=?",

    'GetReportTest'     => "SELECT id,guid,dist,version,platform,perl,state FROM cpanstats.cpanstats WHERE id = ? AND state IN ('pass','fail','na','unknown') ORDER BY id",

    'GetMetabaseByGUID' => 'SELECT * FROM metabase.metabase WHERE guid=?',
    'GetTestersEmail'   => 'SELECT * FROM metabase.testers_email',
    'GetTesters'        => 'SELECT * FROM metabase.testers_email ORDER BY id'
);

lib/CPAN/Testers/WWW/Reports/Mailer.pm  view on Meta::CPAN

        unless($author) {
            $self->_log( "WARN: author not found for distribution [$row->{dist}], [$row->{version}]\n" );
            next;
        }

        $row->{version}  ||= '';
        $row->{platform} ||= '';
        $row->{perl}     ||= '';

        # get author preferences
        my $prefs  = $self->_get_prefs($author) || next;

        # do we need to worry about this author?
        if($prefs->{active} == 2) {
            $self->{counts}{NOMAIL}++;
            $self->_log( "DEBUG: author: $author - not active\n" )    if($self->verbose);
            next;
        }

        # get distribution preferences
        $prefs = $self->_get_prefs($author, $row->{dist});
        $self->_log( "DEBUG: dist prefs: " .($prefs ? 'Found' : 'Not Found')."\n" )                             if($self->verbose);
        next    unless($prefs);
        $self->_log( "DEBUG: dist prefs: ignored=" .($prefs->{ignored} || 0)."\n" )                             if($self->verbose);
        next    if($prefs->{ignored});
        $self->_log( "DEBUG: dist prefs: report=$prefs->{report}, report type=$report_type\n" )                 if($self->verbose);
        next    if($prefs->{report} != $report_type);
        $self->_log( "DEBUG: dist prefs: $row->{state}=" .($prefs->{grades}{$row->{state}}||'undef')."\n" )     if($self->verbose);
        $self->_log( "DEBUG: dist prefs: ALL=" .($prefs->{grades}{ALL}||'undef')."\n" )                         if($self->verbose);
        next    unless($prefs->{grades}{$row->{state}} || $prefs->{grades}{'ALL'});
        $self->_log( "DEBUG: dist prefs: CONTINUE\n" )                                                          if($self->verbose);

        # Check whether distribution version is required.
        # If version set to 'LATEST' check this is the current version, if set
        # to 'ALL' then we should allow EVERYTHING through, otherwise filter
        # on the requested versions.

        if($row->{version} && $prefs->{version} && $prefs->{version} ne 'ALL') {
            if($prefs->{version} eq 'LATEST') {
                my @vers = $self->{CPANPREFS}->get_query('array',$phrasebook{'GetLatestDistVers'},$row->{dist});
                $self->_log( "DEBUG: dist prefs: vers=".(scalar(@vers))."\n" )                  if($self->verbose);
                $self->_log( "DEBUG: dist prefs: version=$vers[0]->[0], $row->{version}\n" )    if($self->verbose);
                next    if(@vers && $vers[0]->[0] ne $row->{version});
            } else {
                $prefs->{version} =~ s/\s*//g;
                my %m = map {$_ => 1} split(',',$prefs->{version});
                $self->_log( "DEBUG: dist prefs: $row->{version}\n" )    if($self->verbose);
                next    unless($m{$row->{version}});
            }
        }

        # Check whether this platform is required.
        if($row->{platform} && $prefs->{platform} && $prefs->{platform} ne 'ALL') {
            $prefs->{platform} =~ s/\s*//g;
            $prefs->{platform} =~ s/,/|/g;
            $prefs->{platform} =~ s/\./\\./g;
            $prefs->{platform} =~ s/^(\w+)\|//;
            if($1 && $1 eq 'NOT') {
                $self->_log( "DEBUG: dist prefs: $row->{platform}, =~ $prefs->{platform}\n" )    if($self->verbose);
                next    if($row->{platform} =~ /$prefs->{platform}/);
            } else {
                $self->_log( "DEBUG: dist prefs: $row->{platform}, !~ $prefs->{platform}\n" )    if($self->verbose);
                next    if($row->{platform} !~ /$prefs->{platform}/);
            }
        }

        # Check whether this perl version is required.
        if($row->{perl} && $prefs->{perl} && $prefs->{perl} ne 'ALL') {
            my $perlv = $row->{perl};
            $perlv = $row->{perl};
            $perlv =~ s/\s.*//;

            $prefs->{perl} =~ s/\s*//g;
            $prefs->{perl} =~ s/,/|/g;
            $prefs->{perl} =~ s/\./\\./g;
            my $v = version->new("$perlv")->numify;
            $prefs->{platform} =~ s/^(\w+)\|//;
            if($1 && $1 eq 'NOT') {
                $self->_log( "DEBUG: dist prefs: $perlv || $v =~ $prefs->{perl}\n" )    if($self->verbose);
                next    if($perlv =~ /$prefs->{perl}/ && $v =~ /$prefs->{perl}/);
            } else {
                $self->_log( "DEBUG: dist prefs: $perlv || $v !~ $prefs->{perl}\n" )    if($self->verbose);
                next    if($perlv !~ /$prefs->{perl}/ && $v !~ /$prefs->{perl}/);
            }
        }

        # Check whether patches are required.
        $self->_log( "DEBUG: dist prefs: patches=$prefs->{patches}, row perl $row->{perl}\n" )    if($self->verbose);
        next    if(!$prefs->{patches} && $row->{perl} =~ /(RC\d+|patch)/);

        # check whether only first instance required
        if($prefs->{tuple} eq 'FIRST') {
            my @count = $self->{CPANPREFS}->get_query('array',$phrasebook{'GetReportCount'}, 
                $row->{platform}, $row->{perl}, $row->{state}, $row->{id}, $row->{dist}, $row->{version});
            $self->_log( "DEBUG: dist prefs: tuple=FIRST, count=".(scalar(@count))."\n" )    if($self->verbose);
            next    if(@count > 0);
        }

        $self->_log( "DEBUG: report is being added to mailshot\n" )    if($self->verbose);

        if($mode eq 'reports') {
            $self->_send_report($author,$row);
        }

        push @{$reports{$author}->{dists}{$row->{dist}}->{versions}{$row->{version}}->{platforms}{$row->{platform}}->{perls}{$row->{perl}}->{states}{uc $row->{state}}->{value}}, ($row->{guid} || $row->{id});

lib/CPAN/Testers/WWW/Reports/Mailer.pm  view on Meta::CPAN


        for my $author (sort keys %reports) {
            $self->_log( "DEBUG: $author\n" )   if($self->verbose);

            my $pause = $self->pause->author($author);
            $tvars{name}   = $pause ? $pause->name : $author;
            $tvars{author} = $author;
            $tvars{dists}  = ();

            # get author preferences
            my $prefs = $self->_get_prefs($author);

            # active:
            # 0 - new author, no correspondance
            # 1 - new author, notification mailed
            # 2 - author requested no mail
            # 3 - author requested summary report

            if(!$prefs->{active} || $prefs->{active} == 0) {
                $tvars{subject} = 'Welcome to CPAN Testers';
                $self->_write_mail('notification.eml',\%tvars);
                $self->{counts}{NEWAUTH}++;

                # insert author defaults, however check that they don't already
                # exists in the system first, in case entries are out of sync.
                my @auth = $self->{CPANPREFS}->get_query('hash',$phrasebook{'GetAuthorPrefs'}, $author);
                $self->{CPANPREFS}->do_query($phrasebook{'InsertAuthorLogin'}, time(), $author) unless(@auth);
                my @dist = $self->{CPANPREFS}->get_query('hash',$phrasebook{'GetDistPrefs'}, $author,'-');
                $self->{CPANPREFS}->do_query($phrasebook{'InsertDistPrefs'}, $author, '-')  unless(@dist);

lib/CPAN/Testers/WWW/Reports/Mailer.pm  view on Meta::CPAN

            $date[5] -= 1;
        }
    }

    my $fulldate = sprintf "%04d%02d%02d000000", $date[5], $date[4], $date[3];
    my @report = $self->{CPANPREFS}->get_query('array',$phrasebook{'GetEarliest'}, $fulldate);
    return 0    unless(@report);
    return $report[0]->[0] || 0;
}

sub _get_prefs {
    my $self = shift;
    my ($author,$dist) = @_;
    my $active = 0;

    return  unless($author);

    # get distribution defaults
    if($author && $dist) {
        if(defined $PREFS{$author}{dists}{$dist}) {
            return $PREFS{$author}{dists}{$dist};
        }

        my @rows = $self->{CPANPREFS}->get_query('hash',$phrasebook{'GetDistPrefs'}, $author,$dist);
        if(@rows) {
            $PREFS{$author}{dists}{$dist} = $self->_parse_prefs($rows[0]);
            return $PREFS{$author}{dists}{$dist};
        }

        # fall through and assume author defaults
    }

    # get author defaults
    if($author) {
        if(defined $PREFS{$author}{default}) {
            return $PREFS{$author}{default};
        }

        my @auth = $self->{CPANPREFS}->get_query('hash',$phrasebook{'GetAuthorPrefs'}, $author);
        if(@auth) {
            $PREFS{$author}{default}{active} = $auth[0]->{active} || 0;

            my @rows = $self->{CPANPREFS}->get_query('hash',$phrasebook{'GetDefaultPrefs'}, $author);
            if(@rows) {
                $PREFS{$author}{default} = $self->_parse_prefs($rows[0]);
                $PREFS{$author}{default}{active} = $rows[0]->{active} || 0;
                return $PREFS{$author}{default};
            } else {
                $self->{CPANPREFS}->do_query($phrasebook{'InsertDistPrefs'}, $author, '-');
                $active = $PREFS{$author}{default}{active};
            }
        }

        # fall through and assume new author
    }

    $dist ||= '-';

    # use global defaults
    my %prefs = (
            active      => $active,
            ignored     => 0,
            report      => 1,
            grades      => {'FAIL' => 1},
            tuple       => 'FIRST',
            version     => 'LATEST',
            patches     => 0,
            perl        => 'ALL',
            platform    => 'ALL',
        );
    $PREFS{$author}{dists}{$dist} = \%prefs;
    return \%prefs;
}

sub _parse_prefs {
    my ($self,$row) = @_;
    my %hash;

    $row->{grade} ||= 'FAIL';
    my %grades = map {$_ => 1} split(',',$row->{grade});

    $hash{grades}   = \%grades;
    $hash{ignored}  = $self->_defined_or($row->{ignored},  0);
    $hash{report}   = $self->_defined_or($row->{report},   1);
    $hash{tuple}    = $self->_defined_or($row->{tuple},    'FIRST');

lib/CPAN/Testers/WWW/Reports/Mailer.pm  view on Meta::CPAN

Returns the last NNTPID processed for the current mode.

=item * _set_lastid

Sets the given NNTPID for the current mode.

=item * _get_author

Returns the author of a given distribution/version.

=item * _get_prefs

Returns the author preferences.

=item * _parse_prefs

Parse a preferences record and returns a hash instance.

=item * _send_report

Repackages a report as an email for an individual author.

=item * _write_mail

Composes and sends a mail message.

lib/CPAN/Testers/WWW/Reports/Mailer.pm  view on Meta::CPAN


Downloads and/or reads a copy of the 01mailrc.txt file.

=back

=head1 SEE ALSO

L<CPAN::Testers::Data::Generator>
L<CPAN::Testers::WWW::Statistics>

F<http://prefs.cpantesters.org/>,
F<http://www.cpantesters.org/>,
F<http://stats.cpantesters.org/>,
F<http://wiki.cpantesters.org/>,
F<http://blog.cpantesters.org/>

=head1 BUGS, PATCHES & FIXES

There are no known bugs at the time of this release. However, if you spot a
bug or are experiencing difficulties, that is not explained within the POD
documentation, please send bug reports and patches to the RT Queue (see below).

t/05setup-db.t  view on Meta::CPAN

    

    my @row = $handles->{CPANPREFS}->get_query('array','select count(*) from cpanstats');
    is($row[0]->[0], 35, "row count for cpanstats");
    @row = $handles->{CPANPREFS}->get_query('array','select count(*) from uploads');
    is($row[0]->[0], 68, "row count for uploads");

    @row = $handles->{CPANPREFS}->get_query('array','select count(*) from articles');
    is($row[0]->[0], 2, "row count for articles");

    @row = $handles->{CPANPREFS}->get_query('array','select count(*) from prefs_authors');
    is($row[0]->[0], 16, "row count for prefs_authors");
    @row = $handles->{CPANPREFS}->get_query('array','select count(*) from prefs_distributions');
    is($row[0]->[0], 16, "row count for prefs_distributions");
}

t/33prefs.t  view on Meta::CPAN


use CPAN::Testers::WWW::Reports::Mailer;

use TestObject;

# -------------------------------------------------------------------
# Variables

my $CONFIG = 't/_DBDIR/preferences.ini';

my %prefs = (
    LBROCARD => {
        'version'   => 'LATEST',
        'ignored'   => 0,
        'perl'      => 'ALL',
        'report'    => '1',
        'tuple'     => 'FIRST',
        'platform'  => 'ALL',
        'patches'   => 0,
        'grades'    => {
            'FAIL'      => 1

t/33prefs.t  view on Meta::CPAN


# -------------------------------------------------------------------
# Tests

SKIP: {
    skip "No supported databases available", 9  unless(-f $CONFIG);

    ok( my $obj = TestObject->load(), "got object" );


    is_deeply($obj->_get_prefs('LBROCARD','-'),                     $prefs{LBROCARD},   'found author prefs - LBROCARD');
    is_deeply($obj->_get_prefs('SAPER','Acme-CPANAuthors-French'),  $prefs{SAPER},      'found author prefs - SAPER');

#use Data::Dumper;
#print STDERR Dumper($obj->_get_prefs('LBROCARD','-'));
#print STDERR Dumper($obj->_get_prefs('SAPER','Acme-CPANAuthors-French','-'));

    my $row  = {};
    my $hash = {
        'version'   => 'LATEST',
        'ignored'   => 0,
        'perl'      => 'ALL',
        'report'    => 1,
        'tuple'     => 'FIRST',
        'platform'  => 'ALL',
        'patches'   => 0,
        'grades'    => {
            'FAIL'      => 1
        }
    };

    is_deeply($obj->_parse_prefs($row), $hash, 'default prefs parse');
#print STDERR Dumper($obj->_parse_prefs($row));

    $row = {
        grade       => 'PASS,FAIL,UNKNOWN,NA',
        ignored     => 1,
        report      => 0,
        tuple       => 'ALL',
        version     => 'ALL',
        patches     => 1,
        perl        => '5.8.8',
        platform    => 'Linux'

t/33prefs.t  view on Meta::CPAN

        'platform'  => 'Linux',
        'patches'   => 1,
        'grades'    => {
            'PASS'      => 1,
            'FAIL'      => 1,
            'UNKNOWN'   => 1,
            'NA'        => 1
        }
    };

    is_deeply($obj->_parse_prefs($row), $hash, 'default prefs parse');
#print STDERR Dumper($obj->_parse_prefs($row));

    is_deeply($obj->_get_prefs('NOONE'),               $prefs{NOONE},  'author not found - NOONE');
    is_deeply($obj->_get_prefs('BARBIE'),              $prefs{BARBIE}, 'found author prefs - BARBIE');
    is_deeply($obj->_get_prefs('SAPER'),               $prefs{SAPER},  'found author prefs - SAPER');
    is_deeply($obj->_get_prefs('SAPER','Fake-Distro'), $prefs{SAPER},  'found author prefs - SAPER - for unset Distro');
}

t/data/61daily.eml  view on Meta::CPAN

To: "Barbie" <BARBIE@cpan.org>
From: CPAN Tester Report Server <do_not_reply@cpantesters.org>
Date: Sat, 29 Dec 2012 22:58:26 +0000
Subject: CPAN Testers Daily Summary Report

Dear Barbie,

Please find below the latest reports for your distributions, generated by CPAN Testers, from the last 24 hours. 

To change your preferences, or disable notifications, please visit the CPAN Testers Preferences system at https://prefs.cpantesters.org.


Finance-Currency-Convert-XE-0.11:
- i486-linux-gnu / 5.8.8:
  - FAIL http://www.cpantesters.org/cpan/report/403032-b19f-3f77-b713-d32bba55d77f

Finance-Currency-Convert-XE-0.12:
- i686-linux / 5.6.2:
  - FAIL http://www.cpantesters.org/cpan/report/427725-b19f-3f77-b713-d32bba55d77f

t/data/61daily.eml  view on Meta::CPAN

- sun4-solaris / 5.10.0:
  - FAIL http://www.cpantesters.org/cpan/report/1686509-b19f-3f77-b713-d32bba55d77f

- sun4-solaris-thread-multi-64int / 5.10.0:
  - FAIL http://www.cpantesters.org/cpan/report/1299178-b19f-3f77-b713-d32bba55d77f



If you have an issue with a particular report, or wish to gain further information from the tester, please use the 'Find A Tester' tool at http://stats.cpantesters.org/cpanmail.html, using the ID or GUID of the report, as listed above, to locate the ...

You can also adjust the frequency and nature of these notifications or unsubscribe from the notifications entirely, by going to the CPAN Testers Preferences website (https://prefs.cpantesters.org) and login with your PAUSE credentials. You can disabl...

Thanks,
The CPAN Testers
-- 
Reports:     http://www.cpantesters.org
Statistics:  http://stats.cpantesters.org
Preferences: https://prefs.cpantesters.org
Wiki:        http://wiki.cpantesters.org
Blog:        http://blog.cpantesters.org

t/data/62daily.eml  view on Meta::CPAN

To: "Barbie" <BARBIE@cpan.org>
From: CPAN Tester Report Server <do_not_reply@cpantesters.org>
Date: Sat, 29 Dec 2012 22:59:40 +0000
Subject: CPAN Testers Daily Summary Report

Dear Barbie,

Please find below the latest reports for your distributions, generated by CPAN Testers, from the last 24 hours. 

To change your preferences, or disable notifications, please visit the CPAN Testers Preferences system at https://prefs.cpantesters.org.


Finance-Currency-Convert-XE-0.03:
- MSWin32-x86-multi-thread / 5.6.1:
  - PASS http://www.cpantesters.org/cpan/report/111291-b19f-3f77-b713-d32bba55d77f

- darwin / 5.8.1:
  - PASS http://www.cpantesters.org/cpan/report/110427-b19f-3f77-b713-d32bba55d77f

Finance-Currency-Convert-XE-0.04:

t/data/62daily.eml  view on Meta::CPAN

  - PASS http://www.cpantesters.org/cpan/report/2890325-b19f-3f77-b713-d32bba55d77f

  - PASS http://www.cpantesters.org/cpan/report/3477122-b19f-3f77-b713-d32bba55d77f

  - PASS http://www.cpantesters.org/cpan/report/3808094-b19f-3f77-b713-d32bba55d77f



If you have an issue with a particular report, or wish to gain further information from the tester, please use the 'Find A Tester' tool at http://stats.cpantesters.org/cpanmail.html, using the ID or GUID of the report, as listed above, to locate the ...

You can also adjust the frequency and nature of these notifications or unsubscribe from the notifications entirely, by going to the CPAN Testers Preferences website (https://prefs.cpantesters.org) and login with your PAUSE credentials. You can disabl...

Thanks,
The CPAN Testers
-- 
Reports:     http://www.cpantesters.org
Statistics:  http://stats.cpantesters.org
Preferences: https://prefs.cpantesters.org
Wiki:        http://wiki.cpantesters.org
Blog:        http://blog.cpantesters.org

t/data/63daily.eml  view on Meta::CPAN

To: "Barbie" <BARBIE@cpan.org>
From: CPAN Tester Report Server <do_not_reply@cpantesters.org>
Date: Sat, 29 Dec 2012 23:00:09 +0000
Subject: CPAN Testers Daily Summary Report

Dear Barbie,

Please find below the latest reports for your distributions, generated by CPAN Testers, from the last 24 hours. 

To change your preferences, or disable notifications, please visit the CPAN Testers Preferences system at https://prefs.cpantesters.org.


Finance-Currency-Convert-XE-0.11:
- i486-linux-gnu / 5.8.8:
  - FAIL http://www.cpantesters.org/cpan/report/403032-b19f-3f77-b713-d32bba55d77f

Finance-Currency-Convert-XE-0.12:
- i686-linux / 5.6.2:
  - FAIL http://www.cpantesters.org/cpan/report/427725-b19f-3f77-b713-d32bba55d77f

t/data/63daily.eml  view on Meta::CPAN

WWW-UsePerl-Journal-Thread-0.12:
- i686-linux-thread-multi / 5.8.8:
  - UNKNOWN http://www.cpantesters.org/cpan/report/4286867-b19f-3f77-b713-d32bba55d77f

  - UNKNOWN http://www.cpantesters.org/cpan/report/4286871-b19f-3f77-b713-d32bba55d77f



If you have an issue with a particular report, or wish to gain further information from the tester, please use the 'Find A Tester' tool at http://stats.cpantesters.org/cpanmail.html, using the ID or GUID of the report, as listed above, to locate the ...

You can also adjust the frequency and nature of these notifications or unsubscribe from the notifications entirely, by going to the CPAN Testers Preferences website (https://prefs.cpantesters.org) and login with your PAUSE credentials. You can disabl...

Thanks,
The CPAN Testers
-- 
Reports:     http://www.cpantesters.org
Statistics:  http://stats.cpantesters.org
Preferences: https://prefs.cpantesters.org
Wiki:        http://wiki.cpantesters.org
Blog:        http://blog.cpantesters.org

t/data/64daily.eml  view on Meta::CPAN

To: "Barbie" <BARBIE@cpan.org>
From: CPAN Tester Report Server <do_not_reply@cpantesters.org>
Date: Sat, 29 Dec 2012 23:00:41 +0000
Subject: CPAN Testers Daily Summary Report

Dear Barbie,

Please find below the latest reports for your distributions, generated by CPAN Testers, from the last 24 hours. 

To change your preferences, or disable notifications, please visit the CPAN Testers Preferences system at https://prefs.cpantesters.org.


Finance-Currency-Convert-XE-0.15:
- i386-freebsd / 5.5.5:
  - NA http://www.cpantesters.org/cpan/report/1237421-b19f-3f77-b713-d32bba55d77f

- i386-freebsd-64int / 5.8.8:
  - FAIL http://www.cpantesters.org/cpan/report/3089291-b19f-3f77-b713-d32bba55d77f

- i386-netbsd-thread-multi / 5.10.0:

t/data/64daily.eml  view on Meta::CPAN



WWW-UsePerl-Journal-Thread-0.12:
- i686-linux-thread-multi / 5.8.8:
  - UNKNOWN http://www.cpantesters.org/cpan/report/4286867-b19f-3f77-b713-d32bba55d77f



If you have an issue with a particular report, or wish to gain further information from the tester, please use the 'Find A Tester' tool at http://stats.cpantesters.org/cpanmail.html, using the ID or GUID of the report, as listed above, to locate the ...

You can also adjust the frequency and nature of these notifications or unsubscribe from the notifications entirely, by going to the CPAN Testers Preferences website (https://prefs.cpantesters.org) and login with your PAUSE credentials. You can disabl...

Thanks,
The CPAN Testers
-- 
Reports:     http://www.cpantesters.org
Statistics:  http://stats.cpantesters.org
Preferences: https://prefs.cpantesters.org
Wiki:        http://wiki.cpantesters.org
Blog:        http://blog.cpantesters.org

t/data/71daily.eml  view on Meta::CPAN

To: "David Cantrell" <DCANTRELL@cpan.org>
From: CPAN Tester Report Server <do_not_reply@cpantesters.org>
Date: Sat, 29 Dec 2012 23:58:09 +0000
Subject: CPAN Testers Daily Summary Report

Dear David Cantrell,

Please find below the latest reports for your distributions, generated by CPAN Testers, from the last 24 hours. 

To change your preferences, or disable notifications, please visit the CPAN Testers Preferences system at https://prefs.cpantesters.org.


CPAN-ParseDistribution-1.1:
- amd64-freebsd / 5.8.9:
  - FAIL http://www.cpantesters.org/cpan/report/4787287-b19f-3f77-b713-d32bba55d77f



Class-DBI-ClassGenerator-1.02:
- i686-linux-thread-multi / 5.8.8:

t/data/71daily.eml  view on Meta::CPAN



Net-Random-2.0:
- i686-linux-thread-multi / 5.8.8:
  - UNKNOWN http://www.cpantesters.org/cpan/report/4638138-b19f-3f77-b713-d32bba55d77f



If you have an issue with a particular report, or wish to gain further information from the tester, please use the 'Find A Tester' tool at http://stats.cpantesters.org/cpanmail.html, using the ID or GUID of the report, as listed above, to locate the ...

You can also adjust the frequency and nature of these notifications or unsubscribe from the notifications entirely, by going to the CPAN Testers Preferences website (https://prefs.cpantesters.org) and login with your PAUSE credentials. You can disabl...

Thanks,
The CPAN Testers
-- 
Reports:     http://www.cpantesters.org
Statistics:  http://stats.cpantesters.org
Preferences: https://prefs.cpantesters.org
Wiki:        http://wiki.cpantesters.org
Blog:        http://blog.cpantesters.org
To: "David Cantrell" <DCANTRELL@cpan.org>
From: CPAN Tester Report Server <do_not_reply@cpantesters.org>
Date: Sat, 29 Dec 2012 23:58:09 +0000
Subject: CPAN Testers Daily Summary Report

Dear David Cantrell,

Please find below the latest reports for your distributions, generated by CPAN Testers, from the last 24 hours. 

To change your preferences, or disable notifications, please visit the CPAN Testers Preferences system at https://prefs.cpantesters.org.


CPAN-ParseDistribution-1.1:
- amd64-freebsd / 5.8.9:
  - FAIL http://www.cpantesters.org/cpan/report/4787287-b19f-3f77-b713-d32bba55d77f



If you have an issue with a particular report, or wish to gain further information from the tester, please use the 'Find A Tester' tool at http://stats.cpantesters.org/cpanmail.html, using the ID or GUID of the report, as listed above, to locate the ...

You can also adjust the frequency and nature of these notifications or unsubscribe from the notifications entirely, by going to the CPAN Testers Preferences website (https://prefs.cpantesters.org) and login with your PAUSE credentials. You can disabl...

Thanks,
The CPAN Testers
-- 
Reports:     http://www.cpantesters.org
Statistics:  http://stats.cpantesters.org
Preferences: https://prefs.cpantesters.org
Wiki:        http://wiki.cpantesters.org
Blog:        http://blog.cpantesters.org
To: "David Cantrell" <DCANTRELL@cpan.org>
From: CPAN Tester Report Server <do_not_reply@cpantesters.org>
Date: Sat, 29 Dec 2012 23:58:09 +0000
Subject: CPAN Testers Daily Summary Report

Dear David Cantrell,

Please find below the latest reports for your distributions, generated by CPAN Testers, from the last 24 hours. 

To change your preferences, or disable notifications, please visit the CPAN Testers Preferences system at https://prefs.cpantesters.org.


CPAN-ParseDistribution-1.1:
- amd64-freebsd / 5.8.9:
  - FAIL http://www.cpantesters.org/cpan/report/4787287-b19f-3f77-b713-d32bba55d77f



If you have an issue with a particular report, or wish to gain further information from the tester, please use the 'Find A Tester' tool at http://stats.cpantesters.org/cpanmail.html, using the ID or GUID of the report, as listed above, to locate the ...

You can also adjust the frequency and nature of these notifications or unsubscribe from the notifications entirely, by going to the CPAN Testers Preferences website (https://prefs.cpantesters.org) and login with your PAUSE credentials. You can disabl...

Thanks,
The CPAN Testers
-- 
Reports:     http://www.cpantesters.org
Statistics:  http://stats.cpantesters.org
Preferences: https://prefs.cpantesters.org
Wiki:        http://wiki.cpantesters.org
Blog:        http://blog.cpantesters.org
To: "David Cantrell" <DCANTRELL@cpan.org>
From: CPAN Tester Report Server <do_not_reply@cpantesters.org>
Date: Sat, 29 Dec 2012 23:58:09 +0000
Subject: CPAN Testers Daily Summary Report

Dear David Cantrell,

Please find below the latest reports for your distributions, generated by CPAN Testers, from the last 24 hours. 

To change your preferences, or disable notifications, please visit the CPAN Testers Preferences system at https://prefs.cpantesters.org.


CPAN-ParseDistribution-1.1:
- amd64-freebsd / 5.8.9:
  - FAIL http://www.cpantesters.org/cpan/report/4787287-b19f-3f77-b713-d32bba55d77f



If you have an issue with a particular report, or wish to gain further information from the tester, please use the 'Find A Tester' tool at http://stats.cpantesters.org/cpanmail.html, using the ID or GUID of the report, as listed above, to locate the ...

You can also adjust the frequency and nature of these notifications or unsubscribe from the notifications entirely, by going to the CPAN Testers Preferences website (https://prefs.cpantesters.org) and login with your PAUSE credentials. You can disabl...

Thanks,
The CPAN Testers
-- 
Reports:     http://www.cpantesters.org
Statistics:  http://stats.cpantesters.org
Preferences: https://prefs.cpantesters.org
Wiki:        http://wiki.cpantesters.org
Blog:        http://blog.cpantesters.org

t/lib/TestEnvironment.pm  view on Meta::CPAN


my %tables = (
    'cpanstats'             => { db => 'cpanstats', sql => 'INSERT INTO cpanstats ( id,guid,state,postdate,tester,dist,version,platform,perl,osname,osvers,fulldate ) VALUES ( ?,?,?,?,?,?,?,?,?,?,?,? )' },
    'uploads'               => { db => 'cpanstats', sql => 'INSERT INTO uploads ( type,author,dist,version,filename,released ) VALUES ( ?,?,?,?,?,? )' },
    'ixlatest'              => { db => 'cpanstats', sql => 'INSERT INTO ixlatest ( dist,version,released,author ) VALUES ( ?,?,?,? )' },
    
    'testers_email'         => { db => 'metabase',  sql => 'INSERT INTO testers_email ( id,resource,fullname,email ) VALUES ( ?,?,?,? )' },

    'articles'              => { db => 'articles',  sql => 'INSERT INTO articles ( id,article ) VALUES ( ?,? )' },

    'prefs_authors'         => { db => 'cpanprefs', sql => 'INSERT INTO prefs_authors ( pauseid,active,lastlogin ) VALUES ( ?,?,? )' },
    'prefs_distributions'   => { db => 'cpanprefs', sql => 'INSERT INTO prefs_distributions ( pauseid,distribution,ignored,report,grade,tuple,version,patches,perl,platform ) VALUES ( ?,?,?,?,?,?,?,?,?,? )' },
    
);

my ($testdb,%handles);
my $DBPATH  = 't/_DBDIR';
my $TMPPATH = 't/_TMPDIR';
my $CONFIG  = 't/_DBDIR/preferences.ini';
my $CONFIG2 = 't/_DBDIR/logging.ini';
my $CONFIG3 = 't/_DBDIR/preferences-daily.ini';
my $CONFIG4 = 't/_DBDIR/preferences-reports.ini';

t/lib/TestEnvironment.pm  view on Meta::CPAN

    my @sql = (
        "DELETE FROM cpanstats",
        "DELETE FROM page_requests",
        "DELETE FROM release_data",
        "DELETE FROM release_summary",
        "DELETE FROM ixlatest",
        "DELETE FROM uploads",
        "DELETE FROM articles",
        "DELETE FROM metabase",
        "DELETE FROM testers_email",
        "DELETE FROM prefs_authors",
        "DELETE FROM prefs_distributions"
    );
    dosql( \@sql );
}

sub ResetPrefs {
    my $data = shift;

    # reset databases
    my @sql = (
        "DELETE FROM prefs_authors",
        "DELETE FROM prefs_distributions"
    );
    dosql( \@sql );

    # load data into tables
    for(@$data){
        s/\s+$//;
        my ($type,@values) = split(/\|/,$_);
        my $table = $type eq 'auth' ? 'prefs_authors' : 'prefs_distributions';
        $handles{CPANPREFS}->do_query( $tables{$table}->{sql}, @values );
    }

    my @pa = $handles{CPANPREFS}->get_query('array','select count(*) from prefs_authors');
    my @pd = $handles{CPANPREFS}->get_query('array','select count(*) from prefs_distributions');

    return($pa[0]->[0],$pd[0]->[0]);
}

sub LoadArticles {
    my @articles = @_;

    for my $id (@articles) {
        my $text = read_file('t/samples/'.$id);
        $handles{CPANPREFS}->do_query('INSERT INTO articles ( id, article ) VALUES ( ?, ? )', $id, $text );

t/lib/TestEnvironment.pm  view on Meta::CPAN

    );

    my @create_articles = (
            'DROP TABLE IF EXISTS articles',
            'CREATE TABLE articles (
                id         int(10) unsigned NOT NULL,
                article    longblob
            )'
    );

    my @create_cpanprefs = (
            'DROP TABLE IF EXISTS `prefs_authors`',
            q{CREATE TABLE `prefs_authors` (
                pauseid     varchar(255) NOT NULL,
                active      int(2) DEFAULT '0',
                lastlogin   varchar(255) DEFAULT NULL,
                PRIMARY KEY (pauseid),
                KEY IXACTIVE (active)
            )},

            'DROP TABLE IF EXISTS prefs_distributions',
            q{CREATE TABLE prefs_distributions (
                pauseid         varchar(255) NOT NULL,
                distribution    varchar(255) NOT NULL,
                ignored         int(1)          DEFAULT '0',
                report          int(2)          DEFAULT '0',
                grade           varchar(32)     DEFAULT 'FAIL',
                tuple           varchar(32)     DEFAULT 'FIRST',
                version         varchar(1000)   DEFAULT 'LATEST',
                patches         int(1)          DEFAULT '0',
                perl            varchar(1000)   DEFAULT 'ALL',
                platform        varchar(1000)   DEFAULT 'ALL',
                PRIMARY KEY (pauseid,distribution),
                KEY IXDIST (distribution)
            )}
    );

    dosql( \@create_cpanstats );
    dosql( \@create_metabase  );
    dosql( \@create_articles  );
    dosql( \@create_cpanprefs );
}

sub dosql {
    my $sql = shift;

    if($testdb) {
        for(@$sql) {
            #diag "SQL: [$db] $_";
            eval { $testdb->dbh->do($_); };
            if($@) {

t/lib/TestEnvironment.pm  view on Meta::CPAN

    # main config
    unlink $CONFIG if -f $CONFIG;
    
    my %opts;
    ($opts{dsn}, $opts{dbuser}, $opts{dbpass}) =  $testdb->connection_info();
    ($opts{driver})    = $opts{dsn} =~ /dbi:([^;:]+)/;
    ($opts{database})  = $opts{dsn} =~ /database=([^;]+)/;
    ($opts{database})  = $opts{dsn} =~ /dbname=([^;]+)/     unless($opts{database});
    ($opts{dbhost})    = $opts{dsn} =~ /host=([^;]+)/;
    ($opts{dbport})    = $opts{dsn} =~ /port=([^;]+)/;
    my %cpanprefs = map {my $v = $opts{$_}; defined($v) ? ($_ => $v) : () }
                        qw(driver database dbfile dbhost dbport dbuser dbpass);

    my $dbcfg = join("\n", map { "$_=$cpanprefs{$_}" } grep { $cpanprefs{$_}} qw(driver database dbfile dbhost dbport dbuser dbpass) );

    my $fh = IO::File->new($CONFIG,'w+') or return;
    print $fh <<PRINT;
[SETTINGS]
mailrc=t/data/01mailrc.txt
verbose=1
nomail=1
logfile=t/_TMPDIR/cpanreps.log
logclean=1

t/lib/TestEnvironment.pm  view on Meta::CPAN


1;

#----------------------------------------------------------------------------
# Notes

#select * from cpanstats where state='cpan' and dist in ('AEAE', 'AI-NeuralNet-BackProp', 'AI-NeuralNet-Mesh', 'AI-NeuralNet-SOM', 'AOL-TOC', 'Abstract-Meta-Class', 'Acme', 'Acme-Anything', 'Acme-BOPE', 'Acme-Brainfuck', 'Acme-Buffy', 'Acme-CPANAutho...
# sqlite> select * from cpanstats where postdate=200901 order by dist limit 20;
# id|guid|state|postdate|tester|dist|version|platform|perl|osname|osvers|date

#select * from prefs_authors where pauseid in ('JHARDING','JBRYAN','VOISCHEV','LBROCARD','JALDHAR','JESSE','INGY','JETEVE','DRRHO','JJORE','ISHIGAKI','ADRIANWIT','SAPER','GARU','ZOFFIX');
#select * from prefs_distributions where pauseid in ('JHARDING','JBRYAN','VOISCHEV','LBROCARD','JALDHAR','JESSE','INGY','JETEVE','DRRHO','JJORE','ISHIGAKI','ADRIANWIT','SAPER','GARU','ZOFFIX');
# pauseid|active|lastlogin
# pauseid|distribution|ignored|report|grade|tuple|version|patches|perl|platform

#select * from uploads where dist in ('AEAE', 'AI-NeuralNet-BackProp', 'AI-NeuralNet-Mesh', 'AI-NeuralNet-SOM', 'AOL-TOC', 'Abstract-Meta-Class', 'Acme', 'Acme-Anything', 'Acme-BOPE', 'Acme-Brainfuck', 'Acme-Buffy', 'Acme-CPANAuthors-Canadian', 'Acme...
# type|author|dist|version|filename|released

#select * from ixlatest where author in ('LBROCARD', 'DRRHO', 'VOISCHEV', 'INGY', 'ISHIGAKI', 'SAPER', 'ZOFFIX', 'GARU', 'JESSE', 'JETEVE', 'JJORE', 'JBRYAN', 'JALDHAR', 'JHARDING', 'ADRIANWIT');
#dist|version|released|author

t/lib/TestObject.pm  view on Meta::CPAN

use warnings;

use CPAN::Testers::WWW::Reports::Mailer;
use File::Path;
use File::Basename;

my %phrasebook = (
    'LastReport'        => "SELECT MAX(id) FROM cpanstats",
    'GetEarliest'       => "SELECT id FROM cpanstats WHERE fulldate > ? ORDER BY id LIMIT 1",

    'FindAuthorType'    => "SELECT pauseid FROM prefs_distributions WHERE report = ?",

    'GetReports'        => "SELECT id,guid,dist,version,platform,perl,state FROM cpanstats WHERE id > ? AND state IN ('pass','fail','na','unknown') ORDER BY id",
    'GetReports2'       => "SELECT c.id,c.guid,c.dist,c.version,c.platform,c.perl,c.state FROM cpanstats AS c INNER JOIN ixlatest AS x ON x.dist=c.dist WHERE c.id > ? AND c.state IN ('pass','fail','na','unknown') AND author IN (%s) ORDER BY c.id",
    'GetReportCount'    => "SELECT id FROM cpanstats WHERE platform=? AND perl=? AND state=? AND id < ? AND dist=? AND version=? LIMIT 2",
    'GetLatestDistVers' => "SELECT version FROM uploads WHERE dist=? ORDER BY released DESC LIMIT 1",
    'GetAuthor'         => "SELECT author FROM uploads WHERE dist=? AND version=? LIMIT 1",
    'GetAuthors'        => "SELECT author,dist,version FROM uploads",

    'GetAuthorPrefs'    => "SELECT * FROM prefs_authors WHERE pauseid=?",
    'GetDefaultPrefs'   => "SELECT * FROM prefs_authors AS a INNER JOIN prefs_distributions AS d ON d.pauseid=a.pauseid AND d.distribution='-' WHERE a.pauseid=?",
    'GetDistPrefs'      => "SELECT * FROM prefs_distributions WHERE pauseid=? AND distribution=?",
    'InsertAuthorLogin' => 'INSERT INTO prefs_authors (active,lastlogin,pauseid) VALUES (1,?,?)',
    'InsertDistPrefs'   => "INSERT INTO prefs_distributions (pauseid,distribution,ignored,report,grade,tuple,version,patches,perl,platform) VALUES (?,?,0,1,'FAIL','FIRST','LATEST',0,'ALL','ALL')",

    'GetArticle'        => "SELECT * FROM articles WHERE id=?",

    'GetReportTest'     => "SELECT id,guid,dist,version,platform,perl,state FROM cpanstats WHERE id = ? AND state IN ('pass','fail','na','unknown') ORDER BY id",

    'GetMetabaseByGUID' => 'SELECT * FROM metabase WHERE guid=?',
    'GetTestersEmail'   => 'SELECT * FROM testers_email',
    'GetTesters'        => 'SELECT * FROM testers_email ORDER BY id'
);

templates/mailer.eml  view on Meta::CPAN

Dear NAME,

Please find below the latest reports for your distributions, generated by CPAN Testers, from the last [% period %]. 

To change your preferences, or disable notifications, please visit the CPAN Testers Preferences system at https://prefs.cpantesters.org.

[% FOREACH dist = dists %]
[% FOREACH vers = dist.versions -%]
[% dist.dist %]-[% vers.version -%]:
[% FOREACH arch = vers.platforms -%]
[% FOREACH pver = arch.perls -%]
- [% arch.platform %] / [% pver.perl %]:
[% FOREACH stat = pver.states -%]
[% FOREACH id = stat.ids -%]
  - [% stat.state %] http://www.cpantesters.org/cpan/report/[% id %]

templates/mailer.eml  view on Meta::CPAN

[% END -%]
[% END -%]
[% END -%]
[% END -%]
[% END -%]

[% END -%]

If you have an issue with a particular report, or wish to gain further information from the tester, please use the 'Find A Tester' tool at http://stats.cpantesters.org/cpanmail.html, using the ID or GUID of the report, as listed above, to locate the ...

You can also adjust the frequency and nature of these notifications or unsubscribe from the notifications entirely, by going to the CPAN Testers Preferences website (https://prefs.cpantesters.org) and login with your PAUSE credentials. You can disabl...

Thanks,
The CPAN Testers

CPAN Testers is only made possible with the support of our sponsors.
For more information on sponsoring, please visit the I ♥ CPAN Testers website (http://iheart.cpantesters.org)

One of our esteemed sponsors is [% SPONSOR_NAME %], [% IF 'Individual Sponsor' == SPONSOR_CATEGORY ; THEN ; 'an' ; ELSE ; 'a' ; END ; %] [% SPONSOR_CATEGORY %].

[% SPONSOR_BODY %]

[% SPONSOR_HREF %]

-- 
Reports:     http://www.cpantesters.org
Statistics:  http://stats.cpantesters.org
Preferences: https://prefs.cpantesters.org
Wiki:        http://wiki.cpantesters.org
Blog:        http://blog.cpantesters.org

templates/notification.eml  view on Meta::CPAN

Dear NAME,

Welcome to possibly your first exposure to the CPAN related community that is CPAN Testers. CPAN Testers are a group of helpful volunteers who automatically download and test distributions as they are uploaded to the CPAN. You are receiving this mail...

But what does this mean to you? Well hopefully you'll discover the benefits of CPAN Testers as we are able to test your distributions on a variety of platforms, using several different Perl versions, and in a selection of different environments. This...

CPAN Testers has been running for over 15 years. With its increased success, and with more and more volunteers adding to the distributed network, it can mean that this feedback can be overwhelming. As such we now implement a CPAN Testers Preferences ...

By default a Daily Summary Report is sent collating a list of FAIL reports for each combination of distribution version, perl version and operating system that have been submitted by the distributed smoke bots over the last 24 hours, which you can th...

The Daily Summary Report is not the only report available, as we also implement Weekly and Monthly Summary Reports. In addition, there is the ability to receive individual reports. All reports are sent based on your specific requirements.

If you choose to not receive these mails, you may still find a list of reports for all your distributions on the CPAN Testers Reports website - http://www.cpantesters.org. The site also includes an RSS feed that is dedicated to your most recent repor...

Once you review your reports, if you have an issue with a particular report, or wish to gain further information from the tester, please use the 'Find A Tester' tool at http://stats.cpantesters.org/cpanmail.html, using the ID of the report to locate ...

If you wish to find out more about CPAN Testers, please check out our Wiki and Blog at the links below.

templates/notification.eml  view on Meta::CPAN


One of our esteemed sponsors is [% SPONSOR_NAME %], [% IF 'Individual Sponsor' == SPONSOR_CATEGORY ; THEN ; 'an' ; ELSE ; 'a' ; END ; %] [% SPONSOR_CATEGORY %].

[% SPONSOR_BODY %]

[% SPONSOR_HREF %]

--
Reports:     http://www.cpantesters.org
Statistics:  http://stats.cpantesters.org
Preferences: https://prefs.cpantesters.org
Wiki:        http://wiki.cpantesters.org
Blog:        http://blog.cpantesters.org



( run in 2.323 seconds using v1.01-cache-2.11-cpan-8f98c5d2c55 )