Merge remote-tracking branch 'calcms/master'
492bc44(calcms/master) lib/calcms/user_sessions.pm: always write session80cbaf7fixup! templates: fix javascript escaping4689deenotify-events: show resultsb7ff85fcreate-events.cgi: remove comments0c7cf10website/agenda/.htaccess: add route for running id61405a2install/create.sql: new index for events6744123calcms.css: use woff2 fonts onlyf71d6e9mail.pm: convert to ascii642e739fixup! lib/calcms: remove comments and shorten expressions
This commit is contained in:
@@ -96,6 +96,7 @@ apt-get install <deb-package>
|
|||||||
libmime-tools-perl
|
libmime-tools-perl
|
||||||
libsession-token-perl
|
libsession-token-perl
|
||||||
libtext-multimarkdown-perl
|
libtext-multimarkdown-perl
|
||||||
|
libtext-unidecode
|
||||||
libtext-wikicreole-perl
|
libtext-wikicreole-perl
|
||||||
liburi-escape-xs-perl
|
liburi-escape-xs-perl
|
||||||
perlmagick
|
perlmagick
|
||||||
|
|||||||
@@ -1816,3 +1816,5 @@ CHANGE COLUMN `email` `email` VARCHAR(100) NULL DEFAULT NULL ;
|
|||||||
|
|
||||||
ALTER TABLE `calcms`.`calcms_user_selected_events`
|
ALTER TABLE `calcms`.`calcms_user_selected_events`
|
||||||
CHANGE COLUMN `user` `user` VARCHAR(100) NOT NULL ;
|
CHANGE COLUMN `user` `user` VARCHAR(100) NOT NULL ;
|
||||||
|
|
||||||
|
CREATE INDEX idx_covering ON calcms_events (start, end, id);
|
||||||
@@ -362,3 +362,5 @@ ADD COLUMN `month` INT UNSIGNED NULL AFTER `week_of_month`,
|
|||||||
CHANGE COLUMN `frequency` `frequency` INT UNSIGNED NULL ;
|
CHANGE COLUMN `frequency` `frequency` INT UNSIGNED NULL ;
|
||||||
|
|
||||||
update `calcms_studio_timeslot_schedule` set period_type = 'days' where period_type = '';
|
update `calcms_studio_timeslot_schedule` set period_type = 'days' where period_type = '';
|
||||||
|
|
||||||
|
CREATE INDEX idx_covering ON calcms_events (start, end, id);
|
||||||
@@ -533,7 +533,7 @@ sub get_listen_key($$){
|
|||||||
my $archive_dir = $config->{locations}->{local_archive_dir};
|
my $archive_dir = $config->{locations}->{local_archive_dir};
|
||||||
my $archive_url = $config->{locations}->{listen_url};
|
my $archive_url = $config->{locations}->{listen_url};
|
||||||
return $event->{listen_url} = $archive_url . '/' . $event->{listen_key} if
|
return $event->{listen_url} = $archive_url . '/' . $event->{listen_key} if
|
||||||
defined $event->{listen_key} and -l $archive_dir .'/'. $event->{listen_key};
|
defined $event->{listen_key} && -l $archive_dir .'/'. $event->{listen_key};
|
||||||
set_listen_key($config, $event) unless $event->{listen_key};
|
set_listen_key($config, $event) unless $event->{listen_key};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,27 @@ package mail;
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
|
use utf8;
|
||||||
|
|
||||||
use Email::Sender::Simple();
|
use Email::Sender::Simple();
|
||||||
use Email::Simple();
|
use Email::Simple();
|
||||||
use MIME::Words qw(encode_mimeword);
|
use Text::Unidecode qw(unidecode);
|
||||||
use MIME::QuotedPrint qw(encode_qp);
|
|
||||||
|
sub to_ascii {
|
||||||
|
my ($s) = @_;
|
||||||
|
my %translate = qw(
|
||||||
|
Ä Ae
|
||||||
|
ä ae
|
||||||
|
Ö Oe
|
||||||
|
ö oe
|
||||||
|
Ü Ue
|
||||||
|
ü ue
|
||||||
|
ß ss
|
||||||
|
);
|
||||||
|
$s =~ s/([ÄäÖöÜüß])/$translate{$1}/g;
|
||||||
|
$s = unidecode $s;
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
|
||||||
sub send($) {
|
sub send($) {
|
||||||
my ($mail) = @_;
|
my ($mail) = @_;
|
||||||
@@ -15,14 +31,13 @@ sub send($) {
|
|||||||
my $email = Email::Simple->create(
|
my $email = Email::Simple->create(
|
||||||
header => [
|
header => [
|
||||||
'Content-Type' => 'text/plain;',
|
'Content-Type' => 'text/plain;',
|
||||||
'Content-Transfer-Encoding' => 'quoted-printable',
|
|
||||||
'From' => $mail->{'From'},
|
'From' => $mail->{'From'},
|
||||||
'To' => $mail->{'To'},
|
'To' => $mail->{'To'},
|
||||||
'Cc' => $mail->{'Cc'},
|
'Cc' => $mail->{'Cc'},
|
||||||
'Reply-To' => $mail->{'Reply-To'},
|
'Reply-To' => $mail->{'Reply-To'},
|
||||||
'Subject' => encode_mimeword($mail->{'Subject'}, 'b', 'UTF-8')
|
'Subject' => to_ascii($mail->{'Subject'})
|
||||||
],
|
],
|
||||||
body => encode_qp($mail->{'Data'}),
|
body => to_ascii($mail->{'Data'})
|
||||||
);
|
);
|
||||||
Email::Sender::Simple->send($email);
|
Email::Sender::Simple->send($email);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -521,7 +521,7 @@ sub delete ($$) {
|
|||||||
sub getDatesWithoutEvent ($$) {
|
sub getDatesWithoutEvent ($$) {
|
||||||
my ($config, $options) = @_;
|
my ($config, $options) = @_;
|
||||||
|
|
||||||
for ('project_id', 'studio_id', 'form', 'till') {
|
for ('project_id', 'studio_id', 'from', 'till') {
|
||||||
return unless defined $options->{$_}
|
return unless defined $options->{$_}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -86,9 +86,11 @@ sub insert ($$) {
|
|||||||
|
|
||||||
$entry->{pid} = $$;
|
$entry->{pid} = $$;
|
||||||
$entry->{expires_at} = time::time_to_datetime( time() + $entry->{timeout} );
|
$entry->{expires_at} = time::time_to_datetime( time() + $entry->{timeout} );
|
||||||
|
$config->{access}->{write} = 1;
|
||||||
my $dbh = db::connect($config);
|
my $dbh = db::connect($config);
|
||||||
return db::insert( $dbh, 'calcms_user_sessions', $entry );
|
my $result = db::insert( $dbh, 'calcms_user_sessions', $entry );
|
||||||
|
$config->{access}->{write} = 0;
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
# start session and return generated session id
|
# start session and return generated session id
|
||||||
@@ -176,6 +178,7 @@ sub update ($$) {
|
|||||||
|
|
||||||
return undef unless defined $entry->{session_id};
|
return undef unless defined $entry->{session_id};
|
||||||
|
|
||||||
|
$config->{access}->{write} = 1;
|
||||||
my $dbh = db::connect($config);
|
my $dbh = db::connect($config);
|
||||||
my @keys = sort keys %$entry;
|
my @keys = sort keys %$entry;
|
||||||
my $values = join( ",", map { $_ . '=?' } @keys );
|
my $values = join( ",", map { $_ . '=?' } @keys );
|
||||||
@@ -187,7 +190,9 @@ sub update ($$) {
|
|||||||
set $values
|
set $values
|
||||||
where session_id=?
|
where session_id=?
|
||||||
};
|
};
|
||||||
return db::put( $dbh, $query, \@bind_values );
|
my $result = db::put( $dbh, $query, \@bind_values );
|
||||||
|
$config->{access}->{write} = 0;
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#map schedule id to id
|
#map schedule id to id
|
||||||
|
|||||||
@@ -1,7 +1,49 @@
|
|||||||
/*
|
* {
|
||||||
include in your web page:
|
border-radius:4px;
|
||||||
<link rel="stylesheet" type="text/css" media="screen" href="/agenda_files/css/calcms.css" />
|
}
|
||||||
*/
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local('Roboto'), local('Roboto-Regular'),
|
||||||
|
url('../fonts/roboto-v18-latin_latin-ext-regular.woff2') format('woff2'),
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local('Open Sans Regular'), local('OpenSans-Regular'),
|
||||||
|
url('../fonts/open-sans-v15-latin_latin-ext-regular.woff2') format('woff2'),
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
html,
|
||||||
|
*,
|
||||||
|
.entry-title a,
|
||||||
|
#calcms_calendar table thead a:hover,
|
||||||
|
#calcms_calendar table thead a:link,
|
||||||
|
.main-navigation a:hover,
|
||||||
|
.main-navigation a:focus
|
||||||
|
{
|
||||||
|
color:white !important;
|
||||||
|
background:black !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#calcms_list h1.summary{
|
||||||
|
background: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.load-prev, a.load-next{
|
||||||
|
color:#999 !important;
|
||||||
|
background:#333 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.custom-logo{
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* fix drupal */
|
/* fix drupal */
|
||||||
input{
|
input{
|
||||||
@@ -676,23 +718,3 @@ ul.mobileMenu li a:hover{
|
|||||||
line-height:2em;
|
line-height:2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
pre{
|
|
||||||
text-align:left;
|
|
||||||
font-family:Courier;
|
|
||||||
padding:1em;
|
|
||||||
margin:1em;
|
|
||||||
border:1px solid black;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.update{
|
|
||||||
position:absolute;
|
|
||||||
bottom:0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.update, div.update a{
|
|
||||||
text-align:left;
|
|
||||||
font-size:6px;
|
|
||||||
color:#bbb;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ my $config = config::get('../config/config.cgi');
|
|||||||
my ( $user, $expires ) = auth::get_user( $config, $params, $cgi );
|
my ( $user, $expires ) = auth::get_user( $config, $params, $cgi );
|
||||||
return if ( ( !defined $user ) || ( $user eq '' ) );
|
return if ( ( !defined $user ) || ( $user eq '' ) );
|
||||||
|
|
||||||
#print STDERR $params->{project_id}."\n";
|
|
||||||
my $user_presets = uac::get_user_presets(
|
my $user_presets = uac::get_user_presets(
|
||||||
$config,
|
$config,
|
||||||
{
|
{
|
||||||
@@ -42,7 +41,6 @@ $params->{default_studio_id} = $user_presets->{studio_id};
|
|||||||
$params = uac::setDefaultStudio( $params, $user_presets );
|
$params = uac::setDefaultStudio( $params, $user_presets );
|
||||||
$params = uac::setDefaultProject( $params, $user_presets );
|
$params = uac::setDefaultProject( $params, $user_presets );
|
||||||
|
|
||||||
#print STDERR $params->{project_id}."\n";
|
|
||||||
my $request = {
|
my $request = {
|
||||||
url => $ENV{QUERY_STRING} || '',
|
url => $ENV{QUERY_STRING} || '',
|
||||||
params => {
|
params => {
|
||||||
@@ -80,7 +78,6 @@ sub show_events {
|
|||||||
uac::permissions_denied('read_events');
|
uac::permissions_denied('read_events');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $events = getDates( $config, $request );
|
my $events = getDates( $config, $request );
|
||||||
$params->{events} = $events;
|
$params->{events} = $events;
|
||||||
$params->{total} = scalar(@$events);
|
$params->{total} = scalar(@$events);
|
||||||
@@ -107,8 +104,6 @@ sub create_events {
|
|||||||
print STDERR "<pre>found " . ( scalar @$dates ) . " dates\n";
|
print STDERR "<pre>found " . ( scalar @$dates ) . " dates\n";
|
||||||
my $events = [];
|
my $events = [];
|
||||||
for my $date (@$dates) {
|
for my $date (@$dates) {
|
||||||
|
|
||||||
#print STDERR $date->{start}."\n";
|
|
||||||
push @$events, createEvent( $config, $request, $date );
|
push @$events, createEvent( $config, $request, $date );
|
||||||
}
|
}
|
||||||
$params->{events} = $events;
|
$params->{events} = $events;
|
||||||
|
|||||||
@@ -2,8 +2,19 @@ table#events{
|
|||||||
transition:all 2s;
|
transition:all 2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
table#events.done{
|
table#events div.error{
|
||||||
background:#cfc;
|
background: #f33;
|
||||||
|
color:white;
|
||||||
|
padding:1rem;
|
||||||
|
width: 30rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
table#events div.done{
|
||||||
|
background: #3f3;
|
||||||
|
color:white;
|
||||||
|
padding:1rem;
|
||||||
|
width: 30rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
table#events td:nth-of-type(1){
|
table#events td:nth-of-type(1){
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
function register_buttons() {
|
function register_buttons() {
|
||||||
$("#forms form").on('click', 'button', function( event ) {
|
$("#forms form").on('click', 'button', function( event ) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var form = $(this).closest('form');
|
let form = $(this).closest('form');
|
||||||
|
let formId = form.attr('id');
|
||||||
|
let table = $('#' + formId+" table");
|
||||||
|
let status = table.find("td.result div");
|
||||||
|
status.text('').removeClass("error").removeClass("done");
|
||||||
|
|
||||||
$.post("notify-events.cgi", form.serialize())
|
$.post("notify-events.cgi", form.serialize())
|
||||||
.done( function(data) {
|
.always( function(data) {
|
||||||
var content = $(data).find("#content");
|
if (data.includes("done")){
|
||||||
$('#result').html(content);
|
status.text("ok").removeClass("error").addClass("done");
|
||||||
var formId = form.attr('id');
|
} else {
|
||||||
$('#' + formId+" table").addClass("done");
|
status.text(data).removeClass("ok").addClass("error");
|
||||||
|
}
|
||||||
|
table.find("tr.result").show();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ no warnings 'redefine';
|
|||||||
use utf8;
|
use utf8;
|
||||||
|
|
||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
|
use Try::Tiny;
|
||||||
|
|
||||||
use params();
|
use params();
|
||||||
use config();
|
use config();
|
||||||
@@ -53,11 +54,10 @@ my $request = {
|
|||||||
|
|
||||||
#set user at params->presets->user
|
#set user at params->presets->user
|
||||||
$request = uac::prepare_request( $request, $user_presets );
|
$request = uac::prepare_request( $request, $user_presets );
|
||||||
|
|
||||||
$params = $request->{params}->{checked};
|
$params = $request->{params}->{checked};
|
||||||
|
|
||||||
#show header
|
#show header
|
||||||
unless ( params::isJson() || ( $params->{template} =~ /\.txt/ ) ) {
|
unless ( params::isJson() || ( $params->{template} =~ /\.txt/ ) || $params->{action}eq'send' ) {
|
||||||
my $headerParams = uac::set_template_permissions( $request->{permissions}, $params );
|
my $headerParams = uac::set_template_permissions( $request->{permissions}, $params );
|
||||||
$headerParams->{loc} = localization::get( $config, { user => $user, file => 'menu' } );
|
$headerParams->{loc} = localization::get( $config, { user => $user, file => 'menu' } );
|
||||||
template::process( $config, 'print', template::check( $config, 'default.html' ), $headerParams );
|
template::process( $config, 'print', template::check( $config, 'default.html' ), $headerParams );
|
||||||
@@ -162,8 +162,13 @@ sub sendMail {
|
|||||||
$mail->{Cc} = $params->{cc} if defined $params->{cc};
|
$mail->{Cc} = $params->{cc} if defined $params->{cc};
|
||||||
$mail->{Subject} = $params->{subject} if defined $params->{subject};
|
$mail->{Subject} = $params->{subject} if defined $params->{subject};
|
||||||
$mail->{Data} = $params->{content} if defined $params->{content};
|
$mail->{Data} = $params->{content} if defined $params->{content};
|
||||||
|
|
||||||
|
try {
|
||||||
my $result = mail::send($mail);
|
my $result = mail::send($mail);
|
||||||
print "Content-type:text/plain\n\nresult:".Dumper($result);
|
print "Content-type:text/plain\n\ndone:$result\n";
|
||||||
|
} catch {
|
||||||
|
printf "Content-type:text/plain\n\nresult:%s\n", $_->{message} // $_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub getMail {
|
sub getMail {
|
||||||
@@ -214,8 +219,6 @@ sub eventToText {
|
|||||||
$s .= $event->{user_excerpt} . "\n";
|
$s .= $event->{user_excerpt} . "\n";
|
||||||
$s .= $event->{topic} . "\n";
|
$s .= $event->{topic} . "\n";
|
||||||
$s .= $event->{content} . "\n";
|
$s .= $event->{content} . "\n";
|
||||||
|
|
||||||
#print STDERR "DUMP\n$s";
|
|
||||||
return $s;
|
return $s;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,3 +28,5 @@ msgstr "Inhalt"
|
|||||||
msgid "show_details"
|
msgid "show_details"
|
||||||
msgstr "Zeige Details"
|
msgstr "Zeige Details"
|
||||||
|
|
||||||
|
msgid "result"
|
||||||
|
msgstr "Ergebnis"
|
||||||
|
|||||||
@@ -28,3 +28,5 @@ msgstr "Content"
|
|||||||
msgid "show_details"
|
msgid "show_details"
|
||||||
msgstr "Show Details"
|
msgstr "Show Details"
|
||||||
|
|
||||||
|
msgid "result"
|
||||||
|
msgstr "Result"
|
||||||
|
|||||||
@@ -63,12 +63,18 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</TMPL_IF>
|
</TMPL_IF>
|
||||||
|
|
||||||
|
<tr class="result" style="display:none">
|
||||||
|
<td><TMPL_VAR .loc.result></td>
|
||||||
|
<td class="result"><div></div></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<TMPL_IF mail.Subject>
|
<TMPL_IF mail.Subject>
|
||||||
<tr class="subject details">
|
<tr class="subject details">
|
||||||
<td><TMPL_VAR .loc.subject></td>
|
<td><TMPL_VAR .loc.subject></td>
|
||||||
<td class="mailSubject"><input name="subject" value="<TMPL_VAR mail.Subject>"></td>
|
<td class="mailSubject"><input name="subject" value="<TMPL_VAR mail.Subject>"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</TMPL_IF>
|
</TMPL_IF>
|
||||||
|
|
||||||
<TMPL_IF mail.From>
|
<TMPL_IF mail.From>
|
||||||
<tr class="details">
|
<tr class="details">
|
||||||
<td><TMPL_VAR .loc.from></td>
|
<td><TMPL_VAR .loc.from></td>
|
||||||
|
|||||||
@@ -66,7 +66,7 @@
|
|||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
class="selectImage"
|
class="selectImage"
|
||||||
onclick="selectImage('<TMPL_VAR name escape=javascript>', '<TMPL_VAR image escape=javascript>', 'studio', '<TMPL_VAR .project_id escape=js>','<TMPL_VAR .studio_id escape=js>'); return false;"
|
onclick="selectImage('<TMPL_VAR name escape=javascript>', '<TMPL_VAR image escape=javascript>', 'studios', '<TMPL_VAR .project_id escape=js>','<TMPL_VAR .studio_id escape=js>'); return false;"
|
||||||
>
|
>
|
||||||
<img id="imagePreview" src="show-image.cgi?project_id=<TMPL_VAR .project_id escape=js>&studio_id=<TMPL_VAR .studio_id escape=js>&filename=<TMPL_VAR image escape=js>&type=icon">
|
<img id="imagePreview" src="show-image.cgi?project_id=<TMPL_VAR .project_id escape=js>&studio_id=<TMPL_VAR .studio_id escape=js>&filename=<TMPL_VAR image escape=js>&type=icon">
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user