diff --git a/Community_News/make_email b/Community_News/make_email index 747d4e1..1e4ea9e 100755 --- a/Community_News/make_email +++ b/Community_News/make_email @@ -5,7 +5,7 @@ # # USAGE: ./make_email [-debug=N] [-month=DATE] [-date=DATE] # [-start=START_TIME] [-end=END_TIME] [-output[=FILE]] -# [-config=FILE] +# [-[no]force] [-config=FILE] # # DESCRIPTION: Make an invitation email for the next Community News # with times per timezone. @@ -37,7 +37,7 @@ # AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com # VERSION: 0.3.3 # CREATED: 2013-10-28 20:35:22 -# REVISION: 2025-02-28 14:40:28 +# REVISION: 2025-04-03 14:42:45 # #=============================================================================== @@ -537,6 +537,7 @@ my $date = $options{date}; my $start = $options{starttime}; my $end = $options{endtime}; my $outfile = $options{output}; +my $force = ( defined( $options{force} ) ? $options{force} : 0 ); my $cfgfile = ( defined( $options{config} ) ? $options{config} : $configfile ); @@ -666,7 +667,7 @@ $dbh->{sqlite_unicode} = 1; my @today = Today(); my @startdate; my @startmonth; -my @reviewdate; +#my @reviewdate; my $monday = 1; # Day of week number 1-7, Monday-Sunday my $offset = day_offset($dayname)->{offset}; @@ -692,7 +693,7 @@ if ( defined($date) ) { $parsed[4] += 1; @startdate = @parsed[ 5, 4, 3 ]; die "Date is in the past '$date'; aborting\n" - unless ( Date_to_Days(@startdate) > Date_to_Days(@today) ); + unless ( $force || Date_to_Days(@startdate) > Date_to_Days(@today) ); } elsif ( defined($month) ) { # @@ -708,7 +709,7 @@ elsif ( defined($month) ) { $parsed[4] += 1; @startmonth = @parsed[ 5, 4, 3 ]; die "Date is in the past '$month'; aborting\n" - unless ( Date_to_Days(@startmonth) > Date_to_Days(@today) ); + unless ( $force || Date_to_Days(@startmonth) > Date_to_Days(@today) ); # # Compute the next meeting date from now (by finding the next first Monday @@ -731,28 +732,25 @@ _debug($DEBUG >= 2, '@startdate: ' . join(',',@startdate)); # The month being reviewed is sometimes the same month and sometimes the month # before. # -if ( $startdate[1] eq $today[1] ) { - # Same month - @reviewdate = @startdate; -} -else { - # Previous month - backup 1 month - @reviewdate = Add_Delta_YM( @startdate, 0, -1 ); -} - -_debug($DEBUG >= 2, '@reviewdate: ' . join(',',@reviewdate)); +#if ( $startdate[1] eq $today[1] ) { +# # Same month +# @reviewdate = @startdate; +#} +#else { +# # Previous month - backup 1 month +# @reviewdate = Add_Delta_YM( @startdate, 0, -1 ); +#} +# +#_debug($DEBUG >= 2, '@reviewdate: ' . join(',',@reviewdate)); # -# Transfer Date::Calc values into hashes for initialising DateTime objects so -# we can play time zone games. (Note: %dtargs is a hash and we're using hash -# slicing to initialise it). +# Transfer Date::Calc values into DateTime objects so +# we can get better formatting. # -my ( %dtargs, $dtstart, $dtend ); -@dtargs{ 'year', 'month', 'day', 'hour', 'minute', 'second', 'time_zone' } - = ( @startdate, @starttime, 'UTC' ); -$dtstart = DateTime->new(%dtargs); -@dtargs{ 'hour', 'minute', 'second' } = (@endtime); -$dtend = DateTime->new(%dtargs); +my ( $dtrevmonth, $dtstart, $dtend ); +$dtrevmonth = dc_to_dt( \@startmonth ); +$dtstart = dc_to_dt( [ @startdate, @starttime ] ); +$dtend = dc_to_dt( [ @startdate, @endtime ] ); # # Compute the number of days until the recording @@ -763,15 +761,31 @@ my $dtf = DateTime::Format::Duration->new( pattern => '%e' ); my $days = $dtf->format_duration($dtoffset); # -# Formatted dates for the mail message body +# Formatted datetime-related values for the mail message body # -my ( $year, $monthno, $monthname, $nicedate, $starttime, $endtime ) = ( - $dtstart->strftime("%Y"), $dtstart->strftime("%m"), - Month_to_Text( $reviewdate[1] ), $dtstart->strftime("%A, %B %d %Y"), - $dtstart->strftime("%R (%Z)"), $dtend->strftime("%R (%Z)"), +my ( $revyear, $revmonthno, $revmonthname ) = ( + $dtrevmonth->year, + $dtrevmonth->month, + $dtrevmonth->month_name +); + +my ( $year, $monthno, $monthname ) = ( + $dtstart->year, + $dtstart->month, + $dtstart->month_name +); + +my ( $nicedate, $starttime, $endtime ) = ( + $dtstart->strftime("%A, %B %d %Y"), + $dtstart->strftime("%R (%Z)"), + $dtend->strftime("%R (%Z)"), ); _debug($DEBUG >= 2, + "----", + "\$revyear: $revyear", + "\$revmonthno: $revmonthno", + "\$revmonthname: $revmonthname", "\$year: $year", "\$monthno: $monthno", "\$monthname: $monthname", @@ -781,7 +795,7 @@ _debug($DEBUG >= 2, ); # -# Build the subject line +# Build the subject line (with the recording date) # my $waittime = ( $days > 6 ? "in $days days" : "next %A" ); my $next = ( $days > 6 ? '' : 'next ' ); @@ -797,7 +811,7 @@ _debug( $DEBUG >= 2, "\$subject: $subject" ); #------------------------------------------------------------------------------- my $outfh; if ($outfile) { - $outfile = sprintf( $outfile, sprintf( "%d-%02d", $year, $monthno ) ) + $outfile = sprintf( $outfile, sprintf( "%d-%02d", $revyear, $revmonthno ) ) if ( $outfile =~ /%s/ ); open( $outfh, ">:encoding(UTF-8)", $outfile ) @@ -861,7 +875,7 @@ $dbh->disconnect; #------------------------------------------------------------------------------- # Update the date cache now we have the date and time details we need. #------------------------------------------------------------------------------- -( my $monthkey = $dtstart->ymd ) =~ s/\d+$/01/; +( my $monthkey = $dtrevmonth->ymd ) =~ s/\d+$/01/; my $datestamp = $dtstart->strftime("%F %T"); if (exists($recdates{$monthkey})) { @@ -899,14 +913,16 @@ my $vars = { subject => $subject, timezones => \@timezones, utc => { - days => $days, - month => $monthname, - year => $year, - date => $nicedate, - start => $starttime, - end => $endtime, + days => $days, + revmonth => $revmonthname, + revyear => $revyear, + month => $monthname, + year => $year, + date => $nicedate, + start => $starttime, + end => $endtime, }, - episode => $episode, # show number + episode => $episode, # show number }; my $document; @@ -1009,7 +1025,7 @@ sub append_cache { # positions for writing (using 'seek'). The now empty file is # filled with data from the hash and closed. # THROWS: No exceptions -# COMMENTS: None +# COMMENTS: Uses 'copy' from File::Copy # SEE ALSO: N/A #=============================================================================== sub update_cache { @@ -1107,6 +1123,56 @@ sub validate_time { return $time; } +#=== FUNCTION ================================================================ +# NAME: dc_to_dt +# PURPOSE: Converts a Date::Calc datetime into a DateTime equivalent +# PARAMETERS: $refdt Reference to an array holding a Date::Calc +# date and time +# RETURNS: Returns a DateTime object converted from the input +# DESCRIPTION: Takes an arrayref which is expected to have a Date::Calc date +# and time. If the referenced array is too short it has three +# zero elements added to it and is checked again, aborting if +# it's still the wrong length. +# THROWS: No exceptions +# COMMENTS: None +# SEE ALSO: N/A +#=============================================================================== +sub dc_to_dt { + my ($refdt) = @_; + + # + # Copy the incoming arrayref into an array to avoid writing data back + # + my @dt = @$refdt; + + # + # Check we got a 6-element array and add a default time if not + # + if (scalar(@dt) < 6) { + push(@dt,0,0,0); + } + + # + # Should be 6 elements now + # + die "Invalid Date::Calc date and time (@dt) in dc_to_dt\n" + unless (scalar(@dt) == 6); + + # + # Convert to DateTime to get access to formatting stuff, default to UTC. + # (Note: %dtargs is a hash and we're using hash slicing to initialise it). + # + my ( %dtargs, $dt ); + @dtargs{ 'year', 'month', 'day', 'hour', 'minute', 'second', 'time_zone' } + = ( @dt, 'UTC' ); + $dt = DateTime->new(%dtargs); + + # + # Return the date and time as a DateTime object + # + return $dt; +} + #=== FUNCTION ================================================================ # NAME: make_date # PURPOSE: Make the event date for recurrence @@ -1331,7 +1397,7 @@ sub Options { "debug=i", "date=s", "starttime=s", "endtime=s", "month=s", "output:s", - "config=s", + "config=s", "force!", ); # "mail!", "fromaddress=s", "toaddress=s", "duration=s", @@ -1362,9 +1428,19 @@ This documentation refers to make_email version 0.3.3 =head1 USAGE make_email [-help] [-documentation] [-debug=N] [-month=DATE] [-date=DATE] - [-start=START_TIME] [-end=END_TIME] [-config=FILE] + [-start=START_TIME] [-end=END_TIME] [-[no]force] [-config=FILE] - ./make_email -date=2022-12-27 + 1. ./make_email -date=2022-12-27 + Generate email for a specific date (in the future) + + 2. ./make_email -force -month=2025-03-01 -start=16:00 -out=HPR_email_%s.txt + Assume this is run in early April 2025. Normally, generating email for + March would not be allowed since it's in the past, so -force is needed + to override the checks. The start day is the default Friday, and the + start time is set to 16:00. The message (email body) is written to + HPR_email_2025-03.txt. The date cache (recording_dates.dat) will be + updated with the line: + 2025-03-01,2025-04-04 16:00:00 =head1 OPTIONS @@ -1474,9 +1550,9 @@ This option defines an output file to receive the mail message text. If the opti omitted the notes are written to STDOUT, allowing them to be redirected if required. -The output file name may contain the characters 'B<%s>'. This denotes the point -at which the year and month in the format B are inserted. For example -if the script is being run for February 2025 the option: +The output file name may contain the characters 'B<%s>'. This denotes the +point at which the year and the review month in the format B are +inserted. For example if the script is being run for February 2025 the option: -out=HPR_email_%s.txt @@ -1484,6 +1560,14 @@ will cause the generation of the file: HPR_email_2025-02.txt +=item B<-[no]force> + +Sometimes the recording of the Community News episode for a month takes place +on the first Friday of the next month. If an attempt is made to run this +script to make the email for such a recording in the month after the review +month, safety checks will prevent it. This option, which is normally off, will +allow the script to run and generate the mail message. + =item B<-config=FILE> This option defines a configuration file other than the default diff --git a/Community_News/make_email_template.tpl b/Community_News/make_email_template.tpl index 4529e54..973ae3a 100644 --- a/Community_News/make_email_template.tpl +++ b/Community_News/make_email_template.tpl @@ -1,11 +1,11 @@ -[%# make_email_template.tpl 2025-02-23 -%] +[%# make_email_template.tpl 2025-04-03 -%] [%# Community News email template -%] [% USE wrap -%] [% subject %] [% FILTER replace('\n', ' ') -%] [% IF utc.days > 6 -%] -The Community News for [% utc.month %] will be recorded using Mumble on +The Community News for [% utc.revmonth %] will be recorded using Mumble on [% ELSE -%] The next Community News will be recorded using Mumble on [% END -%] @@ -14,13 +14,13 @@ The next Community News will be recorded using Mumble on [% FILTER replace('\n', ' ') -%] During the recording HPR Volunteers will review the shows released during -[% utc.month %] [% utc.year %], they will read comments submitted during that +[% utc.revmonth %] [% utc.revyear %], they will read comments submitted during that month, as well as summarising email sent to the HPR mailing list. [% END %] [% FILTER replace('\n', ' ') -%] All HPR listeners are welcome to join in, but we ask that you listen to all -the shows in [% utc.month %] before you do so. +the shows in [% utc.revmonth %] before you do so. [% END %] [% FILTER replace('\n', ' ') -%] @@ -32,18 +32,18 @@ make a change. [% END %] [% FILTER replace('\n', ' ') -%] -The notes for the recording are an extended version of the show notes. These -extended elements are removed before the show is made fully available on the -HPR site (and on archive.org). Comments which might have been missed in the -last recording will be marked in red. Comments which would normally be in this -month, but which were read out in the last show are marked in green. Comments -made in the past month to older shows will be displayed in full (so they are -easier to read). +The notes for the recording are an extended version of the show notes. +A version without these extended elements is made for release on the HPR site +(and on archive.org). Comments which might have been missed in the last +recording will be marked in red in the extended version. Comments which would +normally be in this month, but which were read out in the last show are marked +in green. Comments made in the past month to older shows will be displayed in +full (so they are easier to read). [% END %] [% FILTER replace('\n', ' ') -%] -Look here for the notes for this recording: -https://hackerpublicradio.org/eps/hpr[% episode %]/index.html +The notes for this recording will be made available to participants before the +recording begins. [% END %] Summary: diff --git a/Community_News/recording_dates.dat b/Community_News/recording_dates.dat index 6fc1561..2e8022e 100644 --- a/Community_News/recording_dates.dat +++ b/Community_News/recording_dates.dat @@ -30,4 +30,4 @@ 2024-12-01,2025-01-03 15:00:00 2025-01-01,2025-01-31 15:00:00 2025-02-01,2025-02-28 16:00:00 -2025-03-01,2025-04-04 15:00:00 +2025-03-01,2025-04-04 16:00:00