From 25620ab1f5f9e5d583854d0c5fc09c61457d6b78 Mon Sep 17 00:00:00 2001 From: Milan Date: Sun, 6 Sep 2020 20:00:38 +0200 Subject: [PATCH] listen to records After the end of a show, the audio recordings are uploaded to a directory "listen_dir" under a secret name, beginning with the transmission date "yyyy-mm-dd hh_mm". The directory is available as URL "listen_url", but must not be listable. In order to gain access to the recording for 7 days after the show, a check is done to determine whether the file is available. A random key for the show is stored in the database if a file matching the date is found in listen_dir. With this key as a name, a symbolic link to the original audio file is created. The random name can be used in public documents. If the show data is read again, the key will be retrieved from the database. File access can be restricted by the Apache2 handler ListenerAccess.pm. With it, access to the public symlink is possible for one week. --- install/migrate.sql | 2 + lib/calcms/events.pm | 62 +++++++++++++++++++++ lib/calcms/series_events.pm | 5 +- website/agenda/config/config.cgi.off | 4 ++ website/agenda/templates/event_details.html | 5 ++ 5 files changed, 76 insertions(+), 2 deletions(-) diff --git a/install/migrate.sql b/install/migrate.sql index 6eaa2e7..4b07b59 100644 --- a/install/migrate.sql +++ b/install/migrate.sql @@ -268,3 +268,5 @@ ADD COLUMN `content_format` VARCHAR(45) NULL DEFAULT NULL AFTER `disable_event_s ALTER TABLE `calcms_roles` ADD COLUMN `update_event_field_content_format` TINYINT(1) UNSIGNED NOT NULL AFTER `modified_at`; +ALTER TABLE `calcms_events` +ADD COLUMN `listen_key` VARCHAR(100) NULL; diff --git a/lib/calcms/events.pm b/lib/calcms/events.pm index 655d89a..28af481 100644 --- a/lib/calcms/events.pm +++ b/lib/calcms/events.pm @@ -5,6 +5,9 @@ use warnings; no warnings 'redefine'; use Data::Dumper; +use MIME::Base64(); +use Encode(); + use DBI(); use template(); @@ -176,6 +179,8 @@ sub modify_results ($$$$) { } $result = calc_dates( $config, $result, $params, $previous_result, $time_diff ); + + set_listen_key($config, $result); $result->{event_uri} = ''; if ( ( defined $result->{program} ) && ( $result->{program} ne '' ) ) { @@ -535,6 +540,63 @@ sub calc_dates { return $result; } +sub set_listen_key($$){ + my ($config, $event) =@_; + + my $time_zone = $config->{date}->{time_zone}; + my $start = time::datetime_to_utc( $event->{start_datetime}, $time_zone ); + my $now = time::datetime_to_utc( time::time_to_datetime( time() ), $time_zone); + my $over_since = $now-$start; + return if $over_since < 0; + return if $over_since > 7*24*60*60; + + my $archive_url = $config->{locations}->{listen_url}; + if (defined $event->{listen_key}){ + $event->{listen_url} = $archive_url . '/' . $event->{listen_key}; + return; + } + + my $datetime = $event->{start_datetime}; + if ( $datetime =~ /(\d\d\d\d\-\d\d\-\d\d)[ T](\d\d)\:(\d\d)/ ) { + $datetime = $1 . '\ ' . $2 . '_' . $3; + } else { + print STDERR "update_recording_link: no valid datetime found $datetime\n"; + return; + } + my $archive_dir = $config->{locations}->{local_archive_dir}; + my @files = glob( $archive_dir . '/' . $datetime . '*.mp3' ); + return if @files <= 0; + + my $key = int( rand(99999999999999999) ); + $key = MIME::Base64::encode_base64($key); + $key =~ s/[^a-zA-Z0-9]//g; + $key .='.mp3'; + + my $audio_file = Encode::decode( "UTF-8", $files[0] ); + my $link = $archive_dir . '/' . $key; + symlink $audio_file, $link or die "cannot create $link, $!"; + $event->{listen_url} = $archive_url . '/' . $key; + $event->{listen_key} = $key; + events::update_listen_key($config, $event); +} + +sub update_listen_key($$){ + my ($config, $event) = @_; + + return undef unless defined $event->{event_id}; + return undef unless defined $event->{listen_key}; + print STDERR "set listen_key=$event->{listen_key} for ".$event->{start}." ".$event->{title}."\n"; + my $bindValues = [ $event->{listen_key}, $event->{event_id} ]; + + my $query = qq{ + update calcms_events + set listen_key=? + where id=?; + }; + my $dbh = db::connect($config); + my $recordings = db::put( $dbh, $query, $bindValues ); +} + sub add_recordings($$$$) { my ($dbh, $config, $request, $events) = @_; diff --git a/lib/calcms/series_events.pm b/lib/calcms/series_events.pm index 0a5f45c..7fe5a60 100644 --- a/lib/calcms/series_events.pm +++ b/lib/calcms/series_events.pm @@ -450,7 +450,7 @@ sub insert_event ($$) { #get event content from series for my $attr ( 'program', 'series_name', 'title', 'excerpt', 'content', 'topic', - 'image', 'episode', 'podcast_url', 'archive_url' + 'image', 'episode', 'podcast_url', 'archive_url', 'content_format' ) { $event->{$attr} = $serie->{$attr} if defined $serie->{$attr}; @@ -461,7 +461,8 @@ sub insert_event ($$) { #overwrite series values from parameters for my $attr ( 'program', 'series_name', 'title', 'user_title', 'excerpt', 'user_except', - 'content', 'topic', 'image', 'episode', 'podcast_url', 'archive_url' + 'content', 'topic', 'image', 'episode', 'podcast_url', 'archive_url', + 'content_format' ) { $event->{$attr} = $params->{$attr} if defined $params->{$attr}; diff --git a/website/agenda/config/config.cgi.off b/website/agenda/config/config.cgi.off index 72256cd..1fa65b8 100755 --- a/website/agenda/config/config.cgi.off +++ b/website/agenda/config/config.cgi.off @@ -76,6 +76,10 @@ domain ${DOMAIN} local_archive_dir /home/calcms/archive/ local_archive_url /archive/ + # listen + listen_dir /home/calcms/${DOMAIN}/ + listen_url https://${DOMAIN}/listen/ + local_audio_recordings_dir ${BASE_DIR}/recordings/ local_audio_recordings_url /agenda_files/recordings/ diff --git a/website/agenda/templates/event_details.html b/website/agenda/templates/event_details.html index f6197f6..01c456d 100644 --- a/website/agenda/templates/event_details.html +++ b/website/agenda/templates/event_details.html @@ -60,6 +60,11 @@ + Wiederholung vom , , Uhr