copy current state of medienstaatsvertrag.org, to be verified

This commit is contained in:
Milan
2017-12-18 10:58:50 +01:00
parent 8b35e7c5c2
commit 69e5d0e4c6
401 changed files with 74197 additions and 0 deletions

116
website/agenda/.htaccess Normal file
View File

@@ -0,0 +1,116 @@
<IfModule mod_rewrite.c>
RewriteBase /agenda
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (.*) $1 [L]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*) $1 [L]
RewriteRule ^kommentare/(\d+)/(\d{4}-\d{2}-\d{2}[T\+]\d{2}\:\d{2})(\:\d{2})?/(.*)$ comments.cgi?template=comments.html&event_id=$1&event_start=$2&sort_order=asc&$4 [L]
RewriteRule ^neueste_kommentare/(.*)$ comments.cgi?template=comments_newest.html&limit=20&show_max=3&type=list&$1 [L]
RewriteRule ^feed_kommentare/(.*)$ comments.cgi?template=comments.xml&limit=20&$1 [L]
RewriteRule ^kommentar_neu/(.*)$ add_comment.cgi?$1 [L]
RewriteRule ^sendung/(\d+)/[^&]*(&.*)?$ events.cgi?template=event_details.html&event_id=$1&$2 [L]
RewriteRule ^sendung/(.*)$ events.cgi?$1 [L]
RewriteRule ^sendungen/(\d{4}-\d{2}-\d{2})/(\d{4}-\d{2}-\d{2})/(\d)/(.*)$ events.cgi?template=event_list.html&from_date=$1&till_date=$2&weekday=$3&$4 [L]
RewriteRule ^sendungen/(\d{4}-\d{2}-\d{2})/(\d{4}-\d{2}-\d{2})/(.*)$ events.cgi?template=event_list.html&from_date=$1&till_date=$2&$3 [L]
RewriteRule ^sendungen/(\d{4}-\d{2}-\d{2})/(.*)$ events.cgi?template=event_list.html&date=$1&$2 [L]
RewriteRule ^sendungen/heute/(.*)$ events.cgi?template=event_list.html&date=today&$1 [L]
RewriteRule ^sendungen/(.*)$ events.cgi?$1 [L]
RewriteRule ^menu/(\d{4}-\d{2}-\d{2})/(\d{4}-\d{2}-\d{2})/(\d)/(.*)$ events.cgi?template=event_menu.html&from_date=$1&till_date=$2&weekday=$3&$4 [L]
RewriteRule ^menu/(\d{4}-\d{2}-\d{2})/(\d{4}-\d{2}-\d{2})/(.*)$ events.cgi?template=event_menu.html&from_date=$1&till_date=$2&$3 [L]
RewriteRule ^menu/(\d{4}-\d{2}-\d{2})/(.*)$ events.cgi?template=event_menu.html&date=$1&$2 [L]
RewriteRule ^menu/heute/(.*)$ events.cgi?template=event_menu.html&date=today&$1 [L]
RewriteRule ^menu/(.*)$ events.cgi?$1 [L]
RewriteRule ^kalender/(\d{4}-\d{2}-\d{2})/$ cal.cgi?date=$1 [L]
RewriteRule ^kalender/(\d{4}-\d{2}-\d{2})/(\d{4}-\d{2}-\d{2})/$ cal.cgi?from_date=$1&till_date=$2 [L]
RewriteRule ^kalender/(.*)$ cal.cgi?$1 [L]
RewriteRule ^kategorien/(.*)$ category.cgi?$1 [L]
RewriteRule ^sendereihen/(.*)$ series_names.cgi?$1 [L]
RewriteRule ^playlist/(.*)$ events.cgi?template=event_playlist.html&time=future&limit=5&$1 [L]
RewriteRule ^playlistLong/(.*)$ events.cgi?template=event_playlist_long.html&time=future&limit=20&$1 [L]
RewriteRule ^playlistUtc/(.*)$ events.cgi?template=event_utc_time.json&limit=1
RewriteRule ^running_event/(.*)$ events.cgi?template=event_running.html&time=now&limit=1&$1 [L]
RewriteRule ^feed/(.*)$ events.cgi?template=event.atom.xml&time=future&limit=100&$1 [L]
RewriteRule ^feed.xml[\?]?(.*)$ events.cgi?template=event.atom.xml&time=future&limit=100&$1 [L]
RewriteRule ^atom/(.*)$ events.cgi?template=event.atom.xml&time=future&limit=100&$1 [L]
RewriteRule ^atom.xml[\?]?(.*)$ events.cgi?template=event.atom.xml&time=future&limit=100&$1 [L]
RewriteRule ^rss/(.*)$ events.cgi?template=event.rss.xml&time=future&limit=100&$1 [L]
RewriteRule ^rss.xml[\?]?(.*)$ events.cgi?template=event.rss.xml&time=future&limit=100&$1 [L]
RewriteRule ^ical/(\d{4}-\d{2}-\d{2})/(\d{4}-\d{2}-\d{2})/(\d)/(.*)$ events.cgi?template=event.ics&from_date=$1&till_date=$2&weekday=$3&$4 [L]
RewriteRule ^ical/(\d{4}-\d{2}-\d{2})/(\d{4}-\d{2}-\d{2})/(.*)$ events.cgi?template=event.ics&from_date=$1&till_date=$2&$3 [L]
RewriteRule ^ical/(\d{4}-\d{2})/(.*?)$ events.cgi?template=event.ics&from_date=$1-01&till_date=$1-31&$2 [L]
RewriteRule ^ical/(\d{4}-\d{2}-\d{2})/(.*)$ events.cgi?template=event.ics&date=$1&$2 [L]
RewriteRule ^ical/(\d+)/(.*)?$ events.cgi?template=event.ics&event_id=$1&$2 [L]
RewriteRule ^ical/(.*)$ events.cgi?template=event.ics&$1 [L]
RewriteRule ^ical\.ics[\?]?(.*)$ events.cgi?template=event.ics&$1 [L]
RewriteRule ^suche/(.*?)/(.*?)/kommende/(.*)$ events.cgi?template=event_list.html&project=$1&search=$2&archive=coming&$3 [L]
RewriteRule ^suche/(.*?)/(.*?)/vergangene/(.*)$ events.cgi?template=event_list.html&project=$1&search=$2&archive=gone&$3 [L]
RewriteRule ^suche/(.*?)/(.*?)/(.*)$ events.cgi?template=event_list.html&project=$1&search=$2&$3 [L]
RewriteRule ^suche/(.*?)/(.*)$ events.cgi?template=event_list.html&search=$1&$2 [L]
RewriteRule ^kategorie/(.*?)/(.*?)/kommende/(.*)$ events.cgi?template=event_list.html&project=$1&category=$2&archive=coming&$3 [L]
RewriteRule ^kategorie/(.*?)/(.*?)/vergangene/(.*)$ events.cgi?template=event_list.html&project=$1&category=$2&archive=gone&$3 [L]
RewriteRule ^kategorie/(.*?)/(.*?)/(.*)$ events.cgi?template=event_list.html&project=$1&category=$2&$3 [L]
RewriteRule ^kategorie/(.*?)/(.*)$ events.cgi?template=event_list.html&category=$1&$2 [L]
RewriteRule ^rds/(.*)$ events.cgi?template=event_playlist.txt&time=now&limit=1&$1 [L]
RewriteRule ^playlist_show/(.*)$ events.cgi?template=event_playlist_show.html&time=future&limit=3&$1 [L]
RewriteRule ^json/(.*)$ events.cgi?template=event.json&time=now&limit=15&$1 [L]
RewriteRule ^sendereihe/(.*?)/(.*?)/kommende/(.*)$ events.cgi?template=event_list.html&project=$1&series_name=$2&archive=coming&$3 [L]
RewriteRule ^sendereihe/(.*?)/(.*?)/vergangene/(.*)$ events.cgi?template=event_list.html&project=$1&series_name=$2&archive=gone&$3 [L]
RewriteRule ^sendereihe/(.*?)/(.*?)/(.*)$ events.cgi?template=event_list.html&project=$1&series_name=$2&$3 [L]
RewriteRule ^sendereihe/(.*?)/(.*)$ events.cgi?template=event_list.html&series_name=$1&$2 [L]
RewriteRule ^freefm.xml$ events.cgi?template=event_freefm.xml&location=piradio&limit=40
RewriteRule ^future$ events.cgi?template=event_list_image.html&limit=20
RewriteRule ^dt64-festival.html$ events.cgi?location=dt64&template=event_dt64&archive=all
RewriteRule ^frrapo-programm.html$ events.cgi?location=potsdam&template=event_frrapo
RewriteRule ^upload_playout_piradio$ upload_playout.cgi?project_id=1&studio_id=1
</IfModule>
# MOD_PERL
Options -Indexes +FollowSymLinks +MultiViews +ExecCGI
#PerlResponseHandler ModPerl::RegistryPrefork
<IfModule mod_perl.c>
<FilesMatch "\.cgi$">
SetHandler perl-script
PerlResponseHandler ModPerl::RegistryPrefork
PerlOptions +ParseHeaders
PerlSetVar PerlRunOnce On
Options +ExecCGI
</FilesMatch>
</IfModule>
<IfModule !mod_perl.c>
AddHandler cgi-script .cgi .pl
</IfModule>
#Order allow,deny
#allow from all
Require all granted
## compress
<IfModule mod_headers.c>
# SetOutputFilter DEFLATE
# SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|zip|mp3)$ no-gzip dont-vary
# Header append Vary User-Agent env=!dont-vary
# <FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
# Header set Cache-Control "max-age=600, public"
# </FilesMatch>
</IfModule>

255
website/agenda/add_comment.cgi Executable file
View File

@@ -0,0 +1,255 @@
#! /usr/bin/perl -w
use warnings "all";
use diagnostics;
use strict;
use Data::Dumper;
use CGI qw(header param Vars escapeHTML uploadInfo cgi_error);
$CGI::POST_MAX=1024 * 100;
use params;
use config;
use db;
use markup;
use cache;
use comments;
use template;
use log;
use time;
binmode STDOUT, ":utf8";
my $r=shift;
(my $cgi, my $params, my $error)=params::get($r);
my $config = config::get('./config/config.cgi');
my $debug = $config->{system}->{debug};
$cache::debug=$debug;
my $request={
url => $ENV{QUERY_STRING},
params => {
original => $params,
checked => check_params($config, $params),
},
config => $config,
};
$params=$request->{params}->{checked};
log::init($request);
print $cgi->header('text/plain')."\n";
print STDERR "add comment: ".Dumper($params);
my $comment =$params->{comment};
$config->{access}->{write}=1;
my $dbh=db::connect($config,undef);
print "ok\n";
$comment->{content}=~s/(^|\s)((https?\:\/\/)(.*?))(\s|$|\<)/$1\<a href\=\"$2\"\>$2\<\/a\>$5/g;
$comment->{content}=~s/(^|\s)((https?\:\/\/)(.*?))(\s|$|\<)/$1\<a href\=\"$2\"\>$2\<\/a\>$5/g;
$comment->{content}=~s/(^|\s)((www\.)(.*?))(\s|$|\<)/$1\<a href\=\"http\:\/\/$2\"\>$2\<\/a\>$5/g; #"
$comment->{content}=~s/(^|\s)((www\.)(.*?))(\s|$|\<)/$1\<a href\=\"http\:\/\/$2\"\>$2\<\/a\>$5/g; #"
if (comments::check($dbh, $config, $comment)){
my $nslookup=nslookup();
#if (is_blocked($nslookup)==1){
# send_mail($comment, $nslookup, 'blocked');
# return;
#};
$comment->{comment_id}=comments::insert($dbh, $config, $comment);
if($comment->{comment_id}>0){
comments::update_comment_count($dbh, $config, $comment);
delete_cache($config);
send_mail($comment, $nslookup, 'new');
}
}
sub is_blocked{
my $nslookup=shift;
my $user_agent=$ENV{HTTP_USER_AGENT};
my $block=0;
$block=1 if (
($user_agent eq 'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:35.0) Gecko/20100101 Firefox/35.0')
&& ($nslookup=~/alicedsl/)
);
return $block;
}
sub send_mail{
my $comment = shift;
my $nslookup = shift;
my $status = shift || 'new';
my $ip = $ENV{REMOTE_ADDR}||'';
my $user_agent = $ENV{HTTP_USER_AGENT}||'';
my $cookie = $ENV{HTTP_COOKIE}||'';
my $from = 'no-reply@';
my $to = 'info@';
my $subject = "$status comment from '$comment->{author}': $comment->{content}";
my $content = "$status comment
FROM: '$comment->{author}'
EMAIL: $comment->{email}
CONTENT: '$comment->{content}'
view event
https://piradio.de/programm/sendung/$comment->{event_id}.html#comments
";
if ($status eq 'new'){
$content.="
manage comments:
https://piradio.de/agenda/planung/comment.cgi?project_id=1&studio_id=1
lock this comment
https://piradio.de/agenda/planung/comment.cgi?event_id=$comment->{event_id}&comment_id=$comment->{comment_id}&set_lock_status=blocked
";
}
$content.=qq{
-----------------------------------------------------------
SENDER IP: $ip ($comment->{ip})
USER AGENT: $user_agent
COOKIE: $cookie
$nslookup
};
use MIME::Lite;
my $msg = MIME::Lite->new(
From => $from,
To => $to,
Subject => $subject,
Data => $content
#.Dumper($comment)
);
$msg->send;
}
sub nslookup{
my $ip =$ENV{REMOTE_ADDR};
my $nslookup='';
if($ip=~/^([\d\.]+)$/){
$ip=$1;
return `nslookup '$ip'`;
}
return '';
}
sub delete_cache{
my $config=shift;
unless($config->{locations}->{base_dir}=~/a-zA-Z/){
print STDERR "add_comment.cgi: base_dir is not configured\n";
return;
}
unless($config->{cache}->{cache_dir}=~/a-zA-Z/){
print STDERR "add_comment.cgi: cache_dir is not configured\n";
return;
}
unless($config->{controllers}->{comments}=~/a-zA-Z/){
print STDERR "add_comment.cgi: contoller 'comments' is not configured\n";
return;
}
my $cache_dir=$config->{locations}->{base_dir}.'/'.$config->{cache}->{cache_dir}.'/';
my $widget_cache=$cache_dir.'/'.$config->{controllers}->{comments};
`rm -f $widget_cache/*` if (-d $widget_cache);
my $aggregator_dir=$cache_dir.'/programm/'.$config->{controllers}->{comments};
`rm -f $aggregator_dir/*` if (-d $aggregator_dir);
}
sub check_params{
my $config=shift;
my $params=shift;
my $template=template::check($params->{'template'}, 'comments.html');
my $comment={};
my $event_start=$params->{'event_start'}||'';
if ($event_start=~/^(\d\d\d\d\-\d\d\-\d\d[ T]\d\d\:\d\d)(\:\d\d)?$/){
$comment->{event_start}=$1;
}else{
log::error($config, 'add_comment.cgi: invalid date "'.$event_start.'"');
}
my $event_id=$params->{'event_id'}||'';
if ($event_id=~/^(\d+)$/){
$comment->{event_id}=$1;
}else{
log::error($config, 'add_comment.cgi: invalid id');
}
my $parent_id=$params->{'parent_id'}||'';
if ($parent_id=~/^(\d+)$/){
$comment->{parent_id}=$1;
}else{
$comment->{parent_id}=0;
}
$comment->{content}=$params->{'content'}||'';
$comment->{content}=escape_text($comment->{content});
$comment->{content}=substr($comment->{content},0,1000);
log::error($config, 'add_comment.cgi: missing body') if ($comment->{content}eq'');
$comment->{author}=$params->{'author'}||'';
$comment->{author}=escape_text($comment->{author});
$comment->{author}=substr($comment->{author},0,40);
log::error($config, 'add_comment.cgi: missing name') if ($comment->{author}eq'');
$comment->{email}=$params->{'email'}||'';
$comment->{email}=escape_text($comment->{email});
$comment->{email}=substr($comment->{email},0,40);
$comment->{title}=$params->{'title'}||'';
$comment->{title}=escape_text($comment->{title});
$comment->{title}=substr($comment->{title},0,80);
$comment->{ip}=$ENV{REMOTE_ADDR}||'';
log::error($config, 'missing ip') if ($comment->{ip}eq'');
$comment->{ip}=Digest::MD5::md5_base64($comment->{ip});
my $today=time::datetime_to_array(time::time_to_datetime());
my $date =time::datetime_to_array($comment->{event_start});
my $delta_days=time::days_between($today,$date);
log::error($config, 'add_comment.cgi: no comments allowed, yet') if ($delta_days > $config->{permissions}->{no_new_comments_before} );
log::error($config, 'add_comment.cgi: no comments allowed anymore') if ($delta_days < -1*$config->{permissions}->{no_new_comments_after} );
return {
template =>$template,
comment =>$comment
}
}
sub escape_text{
my $s=shift;
$s=~s/^\s+//g;
$s=~s/\s+$//g;
#remove broken HTML
$s=~s/<[a-z\!\?\[\/][^\>]+?\>//gi;
$s=~s/<[a-z\!\?\[\/]\>//gi;
$s=CGI::escapeHTML($s);
$s=~s/[\n\r]+/\<br \/\>/g;
$s=~s/\<br \/\>/\<br \/\>\n/g;
$s=~s/\<br \/\>\s*$//g;
return $s;
}

170
website/agenda/aggregate.cgi Executable file
View File

@@ -0,0 +1,170 @@
#! /usr/bin/perl -w
use warnings "all";
use strict;
#use Data::Dumper;
#use DBI;
use CGI qw(header param Vars);
#use Time::Local qw(timelocal);
#use Benchmark;
#use Devel::Profiler;
use db;
use events;
use time;
use aggregator;
use markup;
use log;
use config;
#use params;
#my $r=shift;
if ($0=~/aggregate.*?\.cgi$/){
binmode STDOUT, ":encoding(UTF-8)";
#(my $cgi, my $params, my $error)=params::get($r);
my $cgi=new CGI();
my %params=$cgi->Vars();
my $params=\%params;
#print STDERR Dumper($params);
my $config = config::get('config/config.cgi');
my $debug = $config->{system}->{debug};
my $mem_debug = $config->{system}->{debug_memory};
my $base_dir = $config->{locations}->{base_dir};
#my $cgi=new CGI();
my $output_header='';
if(exists $ENV{REQUEST_URI} && $ENV{REQUEST_URI}ne''){
$output_header.="Content-type:text/html; charset=UTF-8;\n\n";
};
# $output_header.='<!DOCTYPE html>'."\n";
my $request={
url => $ENV{QUERY_STRING},
params => {
original => $params,
checked => aggregator::check_params($config, $params),
},
};
$params=$request->{params}->{checked};
my $mem=0;
log::init($request);
#get result from cache
my $cache=aggregator::get_cache($config, $request);
if ((defined $cache->{content}) && ($cache->{content}ne'')){
my $content=$cache->{content};
print $output_header;
print $content;
return;
}
my $content=load_file($base_dir.'./index.html');
$content=$$content||'';
#replace HTML escaped calcms_title span by unescaped one
$content=~s/\&lt\;span id\=&quot\;calcms_title&quot\;\&gt\;[^\&]*\&lt\;\/span\&gt\;/\<span id=\"calcms_title\" \>\<\/span\>/g;
# print $content;
my $list=aggregator::get_list($config, $request);
my $menu={content=>''};
$list->{day}=$params->{date} if ((!defined $list->{day}) || ($list->{day} eq''));
$list->{day}='today' if ($list->{day} eq'' && $params->{date} eq'');
$menu=aggregator::get_menu($config, $request, $list->{day}, $list->{results});
my $calendar=aggregator::get_calendar($config, $request, $list->{day});
my $newest_comments=aggregator::get_newest_comments($config, $request);
#my $newest_comments={};
#db::disconnect($request) if (defined $request && defined $request->{connection});
#print STDERR "$list->{project_title}\n";
#build results list
my $output={};
$output->{calcms_menu} = \$menu->{content};
$output->{calcms_list} = \$list->{content};
$output->{calcms_calendar} = \$calendar->{content};
$output->{calcms_newest_comments} = \$newest_comments->{content};
# $output->{calcms_categories} = load_file($base_dir.'/cache/categories.html');
# $output->{calcms_series_names} = load_file($base_dir.'/cache/series_names.html');
# $output->{calcms_programs} = load_file($base_dir.'/cache/programs.html');
my $url=$list->{url};
my $js=qq{
set('preloaded','1');
set('last_list_url','$url');
};
$content=~s/\/\/\s*(calcms_)?preload/$js/;
#insert results into page
for my $key (keys %$output){
my $val=${$output->{$key}};
my $start=index($val,"<body>");
if ($start!=-1){
$val=substr($val,$start+length('<body>'));
}
my $end=index($val,"</body>");
if ($end!=-1){
$val=substr($val,0,$end);
}
$content=~s/(<(div|span)\s+id="$key".*?>).*?(<\/(div|span)>)/$1$val$3/g;
}
#replace whole element span with id="calcms_title" by value
$list->{project_title}='' unless (defined $list->{project_title});
$content=~s/(<(div|span)\s+id="calcms_title".*?>).*?(<\/(div|span)>)/$list->{project_title}/g;
my $title=$list->{program}||'';
$title.=' - '.$list->{series_name} if ((defined $list->{series_name}) && ($list->{series_name} ne''));
$title.=' - '.$list->{title} if ((defined $list->{title}) && ($list->{title} ne''));
$title=' | '.$title if($title ne'');
$title.='Programmplan';
$title.=' | '.$list->{project_title} if $list->{project_title}ne'';
#$content=~s/(<title>)(.*?)(<\/title>)/$1$title$3/;
$js='';
if ((defined $list->{event_id}) && ($list->{event_id}ne'')){
$js.=qq{showCommentsByEventIdOrEventStart('$list->{event_id}','$list->{start_datetime}')};
}
$content=~s/startCalcms\(\)\;/$js/gi;
#replace link to uncompressed or compressed drupal (first link in <head>)
my @parts=split(/<\/head>/,$content);
$parts[0]=~s|/misc/jquery.js|/agenda_files/js/jquery.js|;
$parts[0]=~s|/sites/default/files/js/[a-z0-9\_]+\.js|/agenda_files/js/jquery.js|;
$content=join('</head>',@parts);
print $output_header;
print $content;
# $r->print("done");
if ($config->{cache}->{use_cache} eq '1'){
$cache->{content}=$content;
log::write($config, 'cache_file',$cache->{filename}) if ($debug);
cache::save($cache);
}
# $config=undef;
$content=undef;
$cache=undef;
log::mem($config, 'aggregate done',$mem) if ($mem_debug>0);
}
sub load_file{
my $filename=shift;
my $content="cannot load '$filename'";
open my $FILE,'<:utf8',$filename or return \$content;
$content=join ("",(<$FILE>));
close $FILE;
return \$content;
}

3
website/agenda/cache/.htaccess vendored Normal file
View File

@@ -0,0 +1,3 @@
Order deny,allow
deny from all

View File

@@ -0,0 +1,2 @@
# racalmas
radio calendar management system

View File

@@ -0,0 +1,2 @@
# racalmas
radio calendar management system

38
website/agenda/cache/programm/.htaccess vendored Normal file
View File

@@ -0,0 +1,38 @@
<IfModule mod_rewrite.c>
RewriteBase /programm
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (.*) $1 [L]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*) $1 [L]
#controller
RewriteRule ^kalender/(\d{4}-\d{2}-\d{2})_(\d{4}-\d{2}-\d{2})\.html[\?]?(.*)$ /agenda/aggregate.cgi?from_date=$1&till_date=$2&$3 [L]
RewriteRule ^kalender/(\d{4}-\d{2}-\d{2})\.html[\?]?(.*)$ /agenda/aggregate.cgi?date=$1&$2 [L]
RewriteRule ^sendungen/(\d{4}-\d{2}-\d{2})\.html[\?]?(.*)$ /agenda/aggregate.cgi?date=$1&$2 [L]
# RewriteRule ^sendung/(\d+)\.html/[^&]*(&.*)?$ /agenda/aggregate.cgi?event_id=$1&$2 [L]
RewriteRule ^sendung/(\d+)\.html[\?]?(.*)$ /agenda/aggregate.cgi?event_id=$1&$2 [L]
RewriteRule ^sendung/serie_plus/(\d+)\.html[\?]?(.*)$ /agenda/aggregate.cgi?next_series=$1&$2 [L]
RewriteRule ^sendung/serie_minus/(\d+)\.html[\?]?(.*)$ /agenda/aggregate.cgi?previous_series=$1&$2 [L]
#controller end
</IfModule>
Options -Indexes +FollowSymLinks +MultiViews +ExecCGI
<IfModule mod_perl.c>
<FilesMatch "\.cgi$">
SetHandler perl-script
PerlHandler ModPerl::RegistryPrefork
PerlSendHeader On
Options +ExecCGI
</FilesMatch>
</IfModule>
<IfModule !mod_perl.c>
AddHandler cgi-script .cgi .pl
</IfModule>
#Order allow,deny
#allow from all
Require all granted

View File

@@ -0,0 +1,2 @@
# racalmas
radio calendar management system

View File

@@ -0,0 +1,2 @@
# racalmas
radio calendar management system

View File

@@ -0,0 +1,2 @@
# racalmas
radio calendar management system

View File

@@ -0,0 +1,2 @@
# racalmas
radio calendar management system

View File

@@ -0,0 +1,2 @@
# racalmas
radio calendar management system

View File

@@ -0,0 +1,2 @@
# racalmas
radio calendar management system

44
website/agenda/cal.cgi Executable file
View File

@@ -0,0 +1,44 @@
#! /usr/bin/perl -w
#use utf8;
use warnings "all";
use strict;
use CGI qw(header param Vars);
$CGI::POST_MAX = 1000;
$CGI::DISABLE_UPLOADS = 1;
use Data::Dumper;
use params;
use config;
use log;
use calendar;
my $r=shift;
#binmode STDOUT, ":utf8";
binmode STDOUT, ":encoding(UTF-8)";
if ($0=~/cal.*?\.cgi$/){
(my $cgi, my $params, my $error)=params::get($r);
my $config=config::get('config/config.cgi');
my $debug=$config->{system}->{debug};
my $request={
url => $ENV{QUERY_STRING},
params => {
original => $params,
checked => calendar::check_params($config, $params),
},
};
$params=$request->{params}->{checked};
log::init($request);
my $out='';
calendar::get_cached_or_render($out, $config, $request);
print $out."\n";
}
1;

145
website/agenda/category.cgi Executable file
View File

@@ -0,0 +1,145 @@
#! /usr/bin/perl -w
use strict;
use warnings;
use Data::Dumper;
use CGI qw(header param Vars);
$CGI::POST_MAX = 1000;
$CGI::DISABLE_UPLOADS = 1;
use params;
use db;
use markup;
use cache;
use log;
use config;
use template;
use project;
binmode STDOUT, ":utf8";
my $r=shift;
(my $cgi, my $params, my $error)=params::get($r);
my $config=config::get('config/config.cgi');
my $debug=$config->{system}->{debug};
my $request={
url => $ENV{QUERY_STRING},
params => {
original => $params,
checked => check_params($config, $params),
},
};
log::init($request);
$params=$request->{params}->{checked};
my $cache={};
if ($config->{cache}->{use_cache} eq '1'){
cache::configure('categories.html');
$cache=cache::load($config, $params);
if (defined $cache->{content}){
print $cache->{content};
return;
};
}
my $dbh=db::connect($config);
my $template_parameters={};
$template_parameters->{projects} = getProjects($dbh, $config);
#$template_parameters->{categories} = get_categories($dbh,$params->{project});
$template_parameters->{debug} = $config->{system}->{debug};
$template_parameters->{server_cache} = $config->{cache}->{server_cache} if ($config->{cache}->{server_cache});
$template_parameters->{use_client_cache}= $config->{cache}->{use_client_cache} if ($config->{cache}->{use_client_cache});
my $template=$params->{template};
my $out='';
template::process($out, $params->{template}, $template_parameters);
print $out;
#write to cache
if ($config->{cache}->{use_cache} eq '1'){
$cache->{content}=$out;
cache::save($cache);
}
sub getProjects{
my $dbh=shift;
my $config=shift;
my $excludedProjects={};
if (defined $config->{filter}->{exclude_projects}){
for my $project ( split(/\,/, $config->{filter}->{exclude_projects}) ){
$project=~s/^\s+//g;
$project=~s/\s+$//g;
$excludedProjects->{$project}=1;
}
}
my $projects=project::get_sorted($config);
my $results=[];
for my $project (@$projects){
next if defined $excludedProjects->{$project->{name}};
my $categories=getCategories($dbh, $config, $project->{name});
$project->{isEmpty}=1 if scalar(@$categories)==0;
$project->{categories}=$categories;
$project->{js_name}=$project->{name};
$project->{js_name}=~s/[^a-zA-Z\_0-9]/\_/g;
$project->{js_name}=~s/\_+/\_/g;
push @$results, $project;
}
return $results;
}
sub getCategories{
my $dbh=shift;
my $config=shift;
my $project=shift;
my $cond='';
my $bind_values=[];
if (($project ne '') && ($project ne 'all')){
$cond='where project=?';
$bind_values=[$project];
}
my $query=qq{
select name, count(name) sum
from calcms_categories
$cond
group by name
order by sum desc, name
};
my $categories=db::get($dbh, $query, $bind_values);
my $results=[];
for my $category (@$categories){
push @$results, $category if $category->{sum}>1;
}
return $results;
}
sub check_params{
my $config=$_[0];
my $params=$_[1];
my $template=template::check($params->{template},'categories.html');
my $debug=$params->{debug}||'';
if ($debug=~/([a-z\_\,]+)/){
$debug=$1;
}
return {
template =>$template,
debug =>$debug
}
}

45
website/agenda/comments.cgi Executable file
View File

@@ -0,0 +1,45 @@
#! /usr/bin/perl -w
use warnings "all";
use strict;
use CGI qw(header param Vars);
$CGI::POST_MAX = 1000;
$CGI::DISABLE_UPLOADS = 1;
use Data::Dumper;
use params;
use config;
use comments;
use db;
use markup;
use time;
use cache;
use log;
my $r=shift;
(my $cgi, my $params, my $error)=params::get($r);
binmode STDOUT, ":encoding(UTF-8)";
if ($0=~/comments.*?\.cgi$/){
my $config=config::get('config/config.cgi');
my $debug=$config->{system}->{debug};
my $request={
url => $ENV{QUERY_STRING},
params => {
original => $params,
checked => comments::check_params($config, $params),
},
};
log::init($request);
my $output='';
comments::get_cached_or_render($output, $config, $request, 'filter_locked');
print $output;
}
#do not delete last line
1;

View File

@@ -0,0 +1,3 @@
Order deny,allow
deny from all
Require all granted

View File

@@ -0,0 +1,125 @@
#!/usr/bin/perl
use CGI qw(header param Vars);
$CGI::POST_MAX = 0;$CGI::DISABLE_UPLOADS = 1;$cgi=new CGI();print $cgi->header();return;exit;
__END__
<config>
# TODO: replace with projects from database
project Corax
# widget support
<controllers>
# controller base directory
domain /agenda/
# customize controller URLs
calendar kalender
event sendung
events sendungen
comments kommentare
ical ical
atom atom
rss rss
</controllers>
# widget support
<templates>
events event_menu.html
events event_list.html
events event_details.html
events event_playlist.html
events event_playlist.txt
events event.ics
events event.atom.xml
events event.rss.xml
events event.json
comments comments.html
comments comments_newest.html
comments comments.xml
aggregator
</templates>
<system>
config_file /home/calcms/website/agenda/config/config.cgi
log_file /var/www/vhosts/system/yourdomain.org/logs/error_log
log_debug_file /home/calcms/log/calcms.log
log_debug_memory_file /home/calcms/log/calcms-mem.log
job_log /home/calcms/log/jobs.log
debug_memory 0
debug 0
</system>
<cache>
use_cache 0
use_client_cache 0
compress 0
cache_dir cache/
base_url /programm
</cache>
<locations>
# URLs of the program page the agenda should be injected into (done by preload_agenda.pl)
# this is the page containing calcms_menu, and other ids
source_url_http http://www.yourdomain.org/programm.html
source_url_https https://www.yourdomain.org/programm.html
# feed base url
source_base_url http://yourdomain.org/
local_base_url /agenda/
# ajax
base_domain http://yourdomain.org/
base_url /agenda/?
base_dir /home/calcms/website/agenda/
static_files_url /agenda/
# images
local_media_dir /home/calcms/website/agenda_files/media/
local_media_url /agenda_files/media/
# archives
local_archive_dir /home/calcms/archive/
local_archive_url /archive/
# synchronization
sync_cms_dir /home/calcms/sync_cms/
# multi language support
admin_pot_dir /home/calcms/website/agenda/planung/pot/
</locations>
<permissions>
result_limit 500
# limit creating comments in days before and after start of event
no_new_comments_before 10
no_new_comments_after 60
</permissions>
<access>
hostname localhost
port 3306
database calcms
username calcms_read
password xxx
username_write calcms_write
password_write xxx
</access>
<date>
time_zone Europe/Berlin
language de
day_starting_hour 6
</date>
</config>

View File

@@ -0,0 +1,17 @@
Options -Indexes +FollowSymLinks +MultiViews -ExecCGI
#Order allow,deny
#allow from all
Require all granted
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 5 minutes"
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(jpg|jpeg|png|gif|js|css|swf)$">
# Header set Cache-Control "public"
Header set Cache-Control "max-age=600, public"
</FilesMatch>
</IfModule>

View File

@@ -0,0 +1,254 @@
/*
wordpress calendar : jero edition
<link rel="stylesheet" type="text/css" media="screen" href="http://www.funkwelle.org/wp-content/uploads/kalender_css/cal.css" />
*/
/* main structure */
/*
body {
font-size:12px
}
*/
#nav {
text-align:center;
margin:0;
height:3em;
z-index:3;
text-align:left;
background:white;
width:100%;
font-size:10px;
}
#calcms_body {
/*
font-size:10px;
*/
overflow:auto;
background:white;
padding-top:3px;padding-right:5px;
margin:bottom:1px;
text-align:left;
padding:3px;
}
pre {
text-align:left;
/*
font-size:0.7em;
*/
font-family:Courier;
padding:1em;margin:1em;
border:1px solid black;
background-color:#eee;
}
/* end of main structure */
/* search field */
#nav form {float:left;}
#nav form input {
/*
font-size:12px;
*/
padding:0;margin:1;border:1px solid gray
}
#nav form select {
/*
font-size:12px;
*/
padding:0;margin:1;border:1px solid gray;width:130px;
}
#nav form option {
/*
font-size:12px;
*/
padding:0;margin:0
}
/* end of search field */
/* event fields */
.calcms_date {
background: #ccccff;
padding:6px;margin:0px;
font-weight:bold;
margin-top:1em;
-moz-border-radius-topleft:6px;
-moz-border-radius-topright:6px;
-webkit-border-top-right-radius: 6px;
-webkit-border-top-left-radius: 6px;
text-align:left
}
.calcms_title {padding:3px;margin:0px;font-weight:bold;text-align:left;}
.calcms_excerpt {padding:3px;margin:0px;background-color:#eee;}
.calcms_content {padding:3px;margin:0px;clear:left;margin:0}
.calcms_content p {margin-top:10px}
.calcms_content h1 {text-align:left;font-size:1.5em;clear:left;margin-top:16px}
.calcms_content h2 {text-align:left;font-size:1.5em;clear:left;margin-top:16px}
.calcms_content h3 {text-align:left;font-size:1.5em;clear:left;margin-top:16px}
.calcms_content h4 {text-align:left;font-size:1.5em;clear:left;margin-top:16px}
.calcms_content li {clear:left;}
.calcms_content img {text-align:left;font-size:1.5em;float:left;margin-right:10px;}/*width:50;height:50px;*/
.calcms_event {text-align:left}
.calcms_day {padding:1px;margin:0px;clear:left;text-align:left}
/* hide microformats */
.dtstart {display:none;visibility:hidden;}
.dtend {display:none;visibility:hidden;}
/* end of event fields */
/* navigation bar */
table#nav{
padding:0;margin:0;width:100%;
border-left:1px solid #88f;
border-top: 1px solid #88f;
text-align:left;
}
table#nav table{
padding:0;margin:0;
border-left:0;border-top:0;
text-align:left;width:100%
}
table#nav table td{
margin:0;text-align:center;
border-bottom:1px solid #88f;
border-right: 1px solid #88f;
}
table#nav table td,
table#nav table a{
padding:1px;
/*
font-size:10px;
*/
}
/* hover effects */
table#nav table td:hover{
border-bottom:1px solid #88f;
border-right :1px solid #88f;
background-color:#f0f0f0;
}
table#nav table td.selected:hover{
background-color:#eee;
border-bottom:1px solid #88f;
border-right: 1px solid #88f;
}
table#nav table a:hover{
}
/* not selectable columns */
table#nav table td.row_type:hover{
border-bottom:1px solid #88f;
border-right: 1px solid #88f;
background-color:#ffffff;
}
.row_type{
width:100px
}
/* selected fields */
#nav .selected, .night, .morning, .noon, .afternoon, .evening{
background:#ddd;
border-bottom:1px solid #88f;
border-right: 1px solid #88f;
-moz-border-radius-topleft:5px;
-moz-border-radius-topright:5px;
-webkit-border-top-right-radius: 5px;
-webkit-border-top-left-radius: 5px;
}
/* end of navigation bar */
/* calendar weeks */
#nav td.week_1,
#nav td.week_2,
#nav td.week_3,
#nav td.week_4,
#nav td.week_5 {
border-right:1px solid #88f ;
}
/* end of calendar weeks */
/* calendar days */
/* replaces the original wp css*/
#wp-calendar {}
#wp-calendar a {padding:2px}
#wp-calendar table {padding:2px}
#wp-calendar td {
/*
font-size:8px;
*/
text-align:center;
background-color:#fefeff;
}
#wp-calendar td a {
padding:2px;
/*
font-size:8px;
*/
font-weight:normal;
}
#wp-calendar a:hover {
background:#eeeeff;
}
/* additional css to mark today and all dates matching to the request */
#wp-calendar .calcms_today {
padding:2px;margin:0px;background:#eeeeee;
}
#wp-calendar td.calcms_match {
background:#ccffcc;
}
#wp-calendar td .selected .calcms_match {
background:#ddeedd;
}
/* end of calendar days */
div.update {
position:absolute;
bottom:0px;
}
div.update , div.update a{
text-align:left;
font-size:6px;
color:#bbb;
}

View File

@@ -0,0 +1,621 @@
/*
include in your web page:
<link rel="stylesheet" type="text/css" media="screen" href="/agenda_files/css/calcms.css" />
*/
/* fix drupal */
input{
max-width:20em;
}
/* hide microformats */
.vevent .dtstart,
.vevent .dtend,
.vevent .location{
display:none;
visibility:hidden;
}
.vevent a{
font-weight:normal;
}
/* end of common */
/* menu */
#calcms_menu{
clear:both;
text-align:left;
}
#calcms_menu .date{
margin:0.5em;
font-weight:bold;
}
#calcms_menu div.event{
padding:0.5em;
}
#calcms_menu div.icon{
width:25px;
margin-right:1em;
float:left;
}
#calcms_menu img{
border:1px solid #ccc;
width:25px;
height:25px;
}
#calcms_menu .title{
padding:0;
margin:0;
line-height:120%;
}
#calcms_menu .event.running{
font-weight:bold;
}
#calcms_menu a:hover{
text-decoration:none;
}
#calcms_menu .event {
transition: all .1s ease-in-out;
}
#calcms_menu .event:hover {
background: #e6e6e6;
}
/* coming events*/
#calcms_playlist{
clear:both;
text-align:left;
}
#calcms_playlist div.event{
padding:0.5em;
}
#calcms_playlist div.icon{
width:25px;
margin-right:1em;
float:left;
}
#calcms_playlist img{
border:1px solid #ccc;
}
#calcms_playlist .title{
padding:0;
margin:0;
text-align:left;
line-height:120%;
}
#calcms_playlist a:hover{
text-decoration:none;
}
#calcms_playlist .event{
transition: all .1s ease-in-out;
}
#calcms_playlist .event:hover {
background: #e6e6e6;
}
/* calcms list */
#calcms_list{
hyphens:auto;
}
#content div a img{
margin:6px;
}
#calcms_list .date{
margin-left:1em;
font-weight:bold;
margin-top:1em;
}
#calcms_list .excerpt{
margin-left:3.1rem;
margin-top:6px;
max-height:5em;
overflow: hidden;
text-overflow: ellipsis;
}
#calcms_list .event.running{
color:#000;
}
#calcms_list .comments.submitted{
font-weight:bold;
}
#calcms_list .submitted{
margin-left:3.2rem;
}
#calcms_list .title{
margin-bottom:1em;
}
#calcms_list .content img{
text-align:left;
font-size:1.5em;
margin-bottom:20px;
border:0;
float: right;
margin-left: 1em;
}
#calcms_list .event{
padding:1em;
padding-top:0.5em;
padding-bottom:0.5em;
margin:1em;
margin-left:0;
background:#eee;
hyphens: none;
cursor:pointer;
}
#calcms_list hr{
margin:1em 0;
background: #ccc;
}
#calcms_list tbody{
border:0;
}
#icon_bar{
text-align:right;
padding:1 em;
}
#icon_bar a {
padding:1em;
}
#calcms_list #playlist_container .event{
padding:0;
margin:0;
overflow:hidden;
}
#calcms_list #playlist_container a{
padding:0;
margin:0;
overflow:hidden;
width:100px;
height:100px;
box-sizing:border-box;
}
/* calcms comments */
#calcms_comments{
clear:both;
}
#calcms_comments .author{
color:#666;
font-weight:bold;
float:left;
}
#calcms_comments .date{
color:#888;
font-weight:normal;
margin:0;
padding:0;
}
#calcms_comments .content{
font-weight:normal;
}
#calcms_comments .comment{
}
#calcms_comments .level0{
margin-left:00px;
}
#calcms_comments .level1{
margin-left:20px;
}
#calcms_comments .level2{
margin-left:40px;
}
#calcms_comments .level3{
margin-left:60px;
}
#calcms_comments .level4{
margin-left:80px;
}
#calcms_comments .level5{
margin-left:100px;
}
#calcms_comments .level6{
margin-left:120px;
}
#calcms_comments .level7{
margin-left:140px;
}
#calcms_comments .level8{
margin-left:160px;
}
#calcms_comments .level9{
margin-left:180px;
}
#calcms_comments .level10{
margin-left:200px;
}
#calcms_add_comment{
visibility:hidden;
display:none;
}
/* calcms add comment */
#calcms_comments input,
#calcms_comments textarea{
appearance: none;
-moz-appearance: none;
-webkit-appearance: none;
box-sizing:border-box;
width:80%;
padding:6px;
margin:6px;
margin-left:0;
border-radius:3px;
border:1px solid #ccc;
box-shadow: 2px 2px 2px rgba(0,0,0,0.1);
}
#calcms_comments input{
max-width:20em;
height:32px;
}
#calcms_comments input[type=submit]{
max-width:10em;
background:#ddd;
}
#calcms_comments input[type="submit"]:hover{
cursor:pointer;
background:#eee;
border:1px solid #aaa;
}
#calcms_comments textarea{
height:10em;
width:40em;
}
/* calcms comment list */
#calcms_newest_comments .author{
font-weight:bold;
}
#calcms_newest_comments div{
padding-left:1em;
padding-bottom:1em;
}
#calcms_newest_comments a:hover{
text-decoration:none;
}
#calcms_newest_comments span.content{
text-overflow: ellipsis;
}
#calcms_newest_comments .comments{
transition: all .1s ease-in-out;
}
#calcms_newest_comments .comments:hover{
background: #e6e6e6;
}
/* end of calcms comments*/
/* calcms_search */
#calcms_search{
margin:0;
padding:0;
z-index:3;
text-align:left;
clear:both;
text-align:center;
}
#calcms_search input,
#calcms_search select{
appearance: none;
-moz-appearance: none;
-webkit-appearance: none;
box-sizing:border-box;
width:80%;
padding:6px;
margin:6px;
margin-left:0;
border-radius:3px;
border:1px solid #ccc;
box-shadow: 2px 2px 2px rgba(0,0,0,0.1);
height:32px;
}
#calcms_search select{
background: white;
background-image: url("/agenda/image/select.png");
background-position: right center;
background-repeat: no-repeat;
}
#calcms_search input[type="checkbox"]{
background: none;
width:1em;
height:1em;
border:1px solid #ccc;
display:inline-block;
box-shadow:0 1px 1px 0 rgba(0, 0, 0, 0.1) inset;
content: " ";
margin-right:1em;
}
#calcms_search input[type="button"]{
background: none;
width:50%;
}
#calcms_search input[type="button"]:hover{
cursor:pointer;
background:#eee;
border:1px solid #aaa;
}
#calcms_search input{}
#calcms_search input#calcms_search_field{}
#calcms_search a#calcms_search_show_details{
padding-left:1em;
display:block;
}
a#calcms_search_show_details #plus{
font-size:16px;
}
/* end of calcms_search */
/* calcms_calendar */
#calcms_calendar{
overflow:hidden;
text-align:center;
padding:0;
margin:0;
vertical-align:top;
clear:both;
}
#calcms_calendar table{
padding:0;
margin:0;
background:#fff;
border:1px solid #ddd;
border-collapse:collapse;
text-align:center;
}
#calcms_calendar table thead a:hover,
#calcms_calendar table thead a:link,
#calcms_calendar table thead a:visited{
color:#333;
padding:0;
text-decoration:none;
font-weight:normal;
}
#calcms_calendar table thead th{
padding-top:0px;
padding-bottom:2px;
}
#calcms_calendar table tbody a:hover,
#calcms_calendar table tbody a:link,
#calcms_calendar table tbody a:visited{
color:#333;
padding:5px;
padding-top:2px;
padding-bottom:3px;
text-decoration:none;
font-weight:normal;
}
#calcms_calendar table td,
#calcms_calendar table th{
padding:0;
margin:0;
border:0;
text-align:center;
font-weight:normal;
border-bottom:1px solid #ddd;
}
#calcms_calendar table thead td:hover,
#calcms_calendar table thead th:hover{
background-color:#ddd;
}
/* header */
#calcms_calendar table th.first,
#calcms_calendar table th.last{
font-size:large;
}
#calcms_calendar table th,
#calcms_calendar table td{
transition: all .1s ease-in-out;
}
/* month selector */
#calcms_calendar table thead tr:first-child a{
padding:6px;
}
#calcms_calendar table thead tr:first-child{
background:#ccc;
}
/* weekdays */
#calcms_calendar table thead tr:nth-child(2) {
background:#eee;
}
/* week numbers */
#calcms_calendar table tbody tr:first-child th:first-child,
#calcms_calendar table tbody tr th:first-child a{
color:#aaa;
}
#calcms_calendar table tbody td:hover,
#calcms_calendar table tbody th:hover{
background-color:#f0f0f0;
}
#calcms_calendar table td.selected{
background:#eee;
font-weight:bold;
}
#calcms_calendar table td.selected:hover{
background-color:#ddd;
}
#calcms_calendar table td.other_month a{
opacity:0.3;
}
/* player */
#player{
border:0;
padding:0;
height:26px;
width:180px;
overflow:hidden;
}
/* mobile menu */
#mobileMenuButton{
display:block;
position:fixed;
z-index:99;
right:6px;
top:3px;
font-size:1.5em;
padding:1em;
line-height:1em;
background:#ddd;
color:#000;
font-weight:bold;
cursor: pointer;
background:#ccc;
background:linear-gradient(to bottom, #333 0%, #333 20%, #bbb 20%, #bbb 40%, #333 40%, #333 60%, #bbb 60%, #bbb 80%, #333 80%, #333 100%);
border:0.4em solid #bbb;
border-radius:6px;
transition:all 0.2s ease-in-out 0s;
}
#mobileMenuButton:hover{
transform: scale(1.05);
}
ul.mobileMenu{
position:fixed;
top:0px;
background:#333!important;
width:100%;
}
ul.mobileMenu li,
ul.mobileMenu li a{
float:none!important;
background:#444!important;
display:block;
text-align:center;
font-size:1.3em;
padding:0.5em!important;
line-height:1em;
z-index:99;
margin-bottom:1px;
width:80%;
}
ul.mobileMenu a,
ul.mobileMenu a:link,
ul.mobileMenu a:hover,
ul.mobileMenu a:visited{
background-image:url()!important;
background:#444!important;
width:80%;
}
ul.mobileMenu li:hover,
ul.mobileMenu li:hover a{
background:#999!important;
transition:all 0.2s ease;
}
ul.mobileMenu li a:hover{
text-decoration:none!important;
}
#footer .content a{
padding:0.5em;
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;
}
*/

View File

@@ -0,0 +1,42 @@
/*
This css is to be included at drupal's programm page type only.
It disables drupal's search block, since calcms needs to use its own.
*/
#search-theme-form {
display: none;
visibility:hidden;
}
.content ul li,
.content ul.menu li,
.content .item-list ul li,
.content li.leaf{
margin:-0.15em 0 -0.15em -0.4em
}
.content ul li{
clear:both;
}
.content ul ul {
margin-left:20px;
}
.content ul ul ul {
margin-left:40px;
}
.content ul ul ul ul {
margin-left:60px;
}
#calcms_menu a:hover,
#calcms_calendar a:hover{
text-decoration:underline;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

1225
website/agenda/css/jquery-ui.css vendored Normal file

File diff suppressed because it is too large Load Diff

7
website/agenda/css/jquery-ui.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,833 @@
/*!
* jQuery UI CSS Framework 1.11.4
* http://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* http://api.jqueryui.com/category/theming/
*/
/* Layout helpers
----------------------------------*/
.ui-helper-hidden {
display: none;
}
.ui-helper-hidden-accessible {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.ui-helper-reset {
margin: 0;
padding: 0;
border: 0;
outline: 0;
line-height: 1.3;
text-decoration: none;
font-size: 100%;
list-style: none;
}
.ui-helper-clearfix:before,
.ui-helper-clearfix:after {
content: "";
display: table;
border-collapse: collapse;
}
.ui-helper-clearfix:after {
clear: both;
}
.ui-helper-clearfix {
min-height: 0; /* support: IE7 */
}
.ui-helper-zfix {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: absolute;
opacity: 0;
filter:Alpha(Opacity=0); /* support: IE8 */
}
.ui-front {
z-index: 100;
}
/* Interaction Cues
----------------------------------*/
.ui-state-disabled {
cursor: default !important;
}
/* Icons
----------------------------------*/
/* states and images */
.ui-icon {
display: block;
text-indent: -99999px;
overflow: hidden;
background-repeat: no-repeat;
}
/* Misc visuals
----------------------------------*/
/* Overlays */
.ui-widget-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.ui-draggable-handle {
-ms-touch-action: none;
touch-action: none;
}
.ui-resizable {
position: relative;
}
.ui-resizable-handle {
position: absolute;
font-size: 0.1px;
display: block;
-ms-touch-action: none;
touch-action: none;
}
.ui-resizable-disabled .ui-resizable-handle,
.ui-resizable-autohide .ui-resizable-handle {
display: none;
}
.ui-resizable-n {
cursor: n-resize;
height: 7px;
width: 100%;
top: -5px;
left: 0;
}
.ui-resizable-s {
cursor: s-resize;
height: 7px;
width: 100%;
bottom: -5px;
left: 0;
}
.ui-resizable-e {
cursor: e-resize;
width: 7px;
right: -5px;
top: 0;
height: 100%;
}
.ui-resizable-w {
cursor: w-resize;
width: 7px;
left: -5px;
top: 0;
height: 100%;
}
.ui-resizable-se {
cursor: se-resize;
width: 12px;
height: 12px;
right: 1px;
bottom: 1px;
}
.ui-resizable-sw {
cursor: sw-resize;
width: 9px;
height: 9px;
left: -5px;
bottom: -5px;
}
.ui-resizable-nw {
cursor: nw-resize;
width: 9px;
height: 9px;
left: -5px;
top: -5px;
}
.ui-resizable-ne {
cursor: ne-resize;
width: 9px;
height: 9px;
right: -5px;
top: -5px;
}
.ui-selectable {
-ms-touch-action: none;
touch-action: none;
}
.ui-selectable-helper {
position: absolute;
z-index: 100;
border: 1px dotted black;
}
.ui-sortable-handle {
-ms-touch-action: none;
touch-action: none;
}
.ui-accordion .ui-accordion-header {
display: block;
cursor: pointer;
position: relative;
margin: 2px 0 0 0;
padding: .5em .5em .5em .7em;
min-height: 0; /* support: IE7 */
font-size: 100%;
}
.ui-accordion .ui-accordion-icons {
padding-left: 2.2em;
}
.ui-accordion .ui-accordion-icons .ui-accordion-icons {
padding-left: 2.2em;
}
.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
position: absolute;
left: .5em;
top: 50%;
margin-top: -8px;
}
.ui-accordion .ui-accordion-content {
padding: 1em 2.2em;
border-top: 0;
overflow: auto;
}
.ui-autocomplete {
position: absolute;
top: 0;
left: 0;
cursor: default;
}
.ui-button {
display: inline-block;
position: relative;
padding: 0;
line-height: normal;
margin-right: .1em;
cursor: pointer;
vertical-align: middle;
text-align: center;
overflow: visible; /* removes extra width in IE */
}
.ui-button,
.ui-button:link,
.ui-button:visited,
.ui-button:hover,
.ui-button:active {
text-decoration: none;
}
/* to make room for the icon, a width needs to be set here */
.ui-button-icon-only {
width: 2.2em;
}
/* button elements seem to need a little more width */
button.ui-button-icon-only {
width: 2.4em;
}
.ui-button-icons-only {
width: 3.4em;
}
button.ui-button-icons-only {
width: 3.7em;
}
/* button text element */
.ui-button .ui-button-text {
display: block;
line-height: normal;
}
.ui-button-text-only .ui-button-text {
padding: .4em 1em;
}
.ui-button-icon-only .ui-button-text,
.ui-button-icons-only .ui-button-text {
padding: .4em;
text-indent: -9999999px;
}
.ui-button-text-icon-primary .ui-button-text,
.ui-button-text-icons .ui-button-text {
padding: .4em 1em .4em 2.1em;
}
.ui-button-text-icon-secondary .ui-button-text,
.ui-button-text-icons .ui-button-text {
padding: .4em 2.1em .4em 1em;
}
.ui-button-text-icons .ui-button-text {
padding-left: 2.1em;
padding-right: 2.1em;
}
/* no icon support for input elements, provide padding by default */
input.ui-button {
padding: .4em 1em;
}
/* button icon element(s) */
.ui-button-icon-only .ui-icon,
.ui-button-text-icon-primary .ui-icon,
.ui-button-text-icon-secondary .ui-icon,
.ui-button-text-icons .ui-icon,
.ui-button-icons-only .ui-icon {
position: absolute;
top: 50%;
margin-top: -8px;
}
.ui-button-icon-only .ui-icon {
left: 50%;
margin-left: -8px;
}
.ui-button-text-icon-primary .ui-button-icon-primary,
.ui-button-text-icons .ui-button-icon-primary,
.ui-button-icons-only .ui-button-icon-primary {
left: .5em;
}
.ui-button-text-icon-secondary .ui-button-icon-secondary,
.ui-button-text-icons .ui-button-icon-secondary,
.ui-button-icons-only .ui-button-icon-secondary {
right: .5em;
}
/* button sets */
.ui-buttonset {
margin-right: 7px;
}
.ui-buttonset .ui-button {
margin-left: 0;
margin-right: -.3em;
}
/* workarounds */
/* reset extra padding in Firefox, see h5bp.com/l */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
border: 0;
padding: 0;
}
.ui-datepicker {
width: 17em;
padding: .2em .2em 0;
display: none;
}
.ui-datepicker .ui-datepicker-header {
position: relative;
padding: .2em 0;
}
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-next {
position: absolute;
top: 2px;
width: 1.8em;
height: 1.8em;
}
.ui-datepicker .ui-datepicker-prev-hover,
.ui-datepicker .ui-datepicker-next-hover {
top: 1px;
}
.ui-datepicker .ui-datepicker-prev {
left: 2px;
}
.ui-datepicker .ui-datepicker-next {
right: 2px;
}
.ui-datepicker .ui-datepicker-prev-hover {
left: 1px;
}
.ui-datepicker .ui-datepicker-next-hover {
right: 1px;
}
.ui-datepicker .ui-datepicker-prev span,
.ui-datepicker .ui-datepicker-next span {
display: block;
position: absolute;
left: 50%;
margin-left: -8px;
top: 50%;
margin-top: -8px;
}
.ui-datepicker .ui-datepicker-title {
margin: 0 2.3em;
line-height: 1.8em;
text-align: center;
}
.ui-datepicker .ui-datepicker-title select {
font-size: 1em;
margin: 1px 0;
}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year {
width: 45%;
}
.ui-datepicker table {
width: 100%;
font-size: .9em;
border-collapse: collapse;
margin: 0 0 .4em;
}
.ui-datepicker th {
padding: .7em .3em;
text-align: center;
font-weight: bold;
border: 0;
}
.ui-datepicker td {
border: 0;
padding: 1px;
}
.ui-datepicker td span,
.ui-datepicker td a {
display: block;
padding: .2em;
text-align: right;
text-decoration: none;
}
.ui-datepicker .ui-datepicker-buttonpane {
background-image: none;
margin: .7em 0 0 0;
padding: 0 .2em;
border-left: 0;
border-right: 0;
border-bottom: 0;
}
.ui-datepicker .ui-datepicker-buttonpane button {
float: right;
margin: .5em .2em .4em;
cursor: pointer;
padding: .2em .6em .3em .6em;
width: auto;
overflow: visible;
}
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
float: left;
}
/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi {
width: auto;
}
.ui-datepicker-multi .ui-datepicker-group {
float: left;
}
.ui-datepicker-multi .ui-datepicker-group table {
width: 95%;
margin: 0 auto .4em;
}
.ui-datepicker-multi-2 .ui-datepicker-group {
width: 50%;
}
.ui-datepicker-multi-3 .ui-datepicker-group {
width: 33.3%;
}
.ui-datepicker-multi-4 .ui-datepicker-group {
width: 25%;
}
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
border-left-width: 0;
}
.ui-datepicker-multi .ui-datepicker-buttonpane {
clear: left;
}
.ui-datepicker-row-break {
clear: both;
width: 100%;
font-size: 0;
}
/* RTL support */
.ui-datepicker-rtl {
direction: rtl;
}
.ui-datepicker-rtl .ui-datepicker-prev {
right: 2px;
left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next {
left: 2px;
right: auto;
}
.ui-datepicker-rtl .ui-datepicker-prev:hover {
right: 1px;
left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next:hover {
left: 1px;
right: auto;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane {
clear: right;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button {
float: left;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
.ui-datepicker-rtl .ui-datepicker-group {
float: right;
}
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
border-right-width: 0;
border-left-width: 1px;
}
.ui-dialog {
overflow: hidden;
position: absolute;
top: 0;
left: 0;
padding: .2em;
outline: 0;
}
.ui-dialog .ui-dialog-titlebar {
padding: .4em 1em;
position: relative;
}
.ui-dialog .ui-dialog-title {
float: left;
margin: .1em 0;
white-space: nowrap;
width: 90%;
overflow: hidden;
text-overflow: ellipsis;
}
.ui-dialog .ui-dialog-titlebar-close {
position: absolute;
right: .3em;
top: 50%;
width: 20px;
margin: -10px 0 0 0;
padding: 1px;
height: 20px;
}
.ui-dialog .ui-dialog-content {
position: relative;
border: 0;
padding: .5em 1em;
background: none;
overflow: auto;
}
.ui-dialog .ui-dialog-buttonpane {
text-align: left;
border-width: 1px 0 0 0;
background-image: none;
margin-top: .5em;
padding: .3em 1em .5em .4em;
}
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
float: right;
}
.ui-dialog .ui-dialog-buttonpane button {
margin: .5em .4em .5em 0;
cursor: pointer;
}
.ui-dialog .ui-resizable-se {
width: 12px;
height: 12px;
right: -5px;
bottom: -5px;
background-position: 16px 16px;
}
.ui-draggable .ui-dialog-titlebar {
cursor: move;
}
.ui-menu {
list-style: none;
padding: 0;
margin: 0;
display: block;
outline: none;
}
.ui-menu .ui-menu {
position: absolute;
}
.ui-menu .ui-menu-item {
position: relative;
margin: 0;
padding: 3px 1em 3px .4em;
cursor: pointer;
min-height: 0; /* support: IE7 */
/* support: IE10, see #8844 */
list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
}
.ui-menu .ui-menu-divider {
margin: 5px 0;
height: 0;
font-size: 0;
line-height: 0;
border-width: 1px 0 0 0;
}
.ui-menu .ui-state-focus,
.ui-menu .ui-state-active {
margin: -1px;
}
/* icon support */
.ui-menu-icons {
position: relative;
}
.ui-menu-icons .ui-menu-item {
padding-left: 2em;
}
/* left-aligned */
.ui-menu .ui-icon {
position: absolute;
top: 0;
bottom: 0;
left: .2em;
margin: auto 0;
}
/* right-aligned */
.ui-menu .ui-menu-icon {
left: auto;
right: 0;
}
.ui-progressbar {
height: 2em;
text-align: left;
overflow: hidden;
}
.ui-progressbar .ui-progressbar-value {
margin: -1px;
height: 100%;
}
.ui-progressbar .ui-progressbar-overlay {
background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
height: 100%;
filter: alpha(opacity=25); /* support: IE8 */
opacity: 0.25;
}
.ui-progressbar-indeterminate .ui-progressbar-value {
background-image: none;
}
.ui-selectmenu-menu {
padding: 0;
margin: 0;
position: absolute;
top: 0;
left: 0;
display: none;
}
.ui-selectmenu-menu .ui-menu {
overflow: auto;
/* Support: IE7 */
overflow-x: hidden;
padding-bottom: 1px;
}
.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
font-size: 1em;
font-weight: bold;
line-height: 1.5;
padding: 2px 0.4em;
margin: 0.5em 0 0 0;
height: auto;
border: 0;
}
.ui-selectmenu-open {
display: block;
}
.ui-selectmenu-button {
display: inline-block;
overflow: hidden;
position: relative;
text-decoration: none;
cursor: pointer;
}
.ui-selectmenu-button span.ui-icon {
right: 0.5em;
left: auto;
margin-top: -8px;
position: absolute;
top: 50%;
}
.ui-selectmenu-button span.ui-selectmenu-text {
text-align: left;
padding: 0.4em 2.1em 0.4em 1em;
display: block;
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.ui-slider {
position: relative;
text-align: left;
}
.ui-slider .ui-slider-handle {
position: absolute;
z-index: 2;
width: 1.2em;
height: 1.2em;
cursor: default;
-ms-touch-action: none;
touch-action: none;
}
.ui-slider .ui-slider-range {
position: absolute;
z-index: 1;
font-size: .7em;
display: block;
border: 0;
background-position: 0 0;
}
/* support: IE8 - See #6727 */
.ui-slider.ui-state-disabled .ui-slider-handle,
.ui-slider.ui-state-disabled .ui-slider-range {
filter: inherit;
}
.ui-slider-horizontal {
height: .8em;
}
.ui-slider-horizontal .ui-slider-handle {
top: -.3em;
margin-left: -.6em;
}
.ui-slider-horizontal .ui-slider-range {
top: 0;
height: 100%;
}
.ui-slider-horizontal .ui-slider-range-min {
left: 0;
}
.ui-slider-horizontal .ui-slider-range-max {
right: 0;
}
.ui-slider-vertical {
width: .8em;
height: 100px;
}
.ui-slider-vertical .ui-slider-handle {
left: -.3em;
margin-left: 0;
margin-bottom: -.6em;
}
.ui-slider-vertical .ui-slider-range {
left: 0;
width: 100%;
}
.ui-slider-vertical .ui-slider-range-min {
bottom: 0;
}
.ui-slider-vertical .ui-slider-range-max {
top: 0;
}
.ui-spinner {
position: relative;
display: inline-block;
overflow: hidden;
padding: 0;
vertical-align: middle;
}
.ui-spinner-input {
border: none;
background: none;
color: inherit;
padding: 0;
margin: .2em 0;
vertical-align: middle;
margin-left: .4em;
margin-right: 22px;
}
.ui-spinner-button {
width: 16px;
height: 50%;
font-size: .5em;
padding: 0;
margin: 0;
text-align: center;
position: absolute;
cursor: default;
display: block;
overflow: hidden;
right: 0;
}
/* more specificity required here to override default borders */
.ui-spinner a.ui-spinner-button {
border-top: none;
border-bottom: none;
border-right: none;
}
/* vertically center icon */
.ui-spinner .ui-icon {
position: absolute;
margin-top: -8px;
top: 50%;
left: 0;
}
.ui-spinner-up {
top: 0;
}
.ui-spinner-down {
bottom: 0;
}
/* TR overrides */
.ui-spinner .ui-icon-triangle-1-s {
/* need to fix icons sprite */
background-position: -65px -16px;
}
.ui-tabs {
position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
padding: .2em;
}
.ui-tabs .ui-tabs-nav {
margin: 0;
padding: .2em .2em 0;
}
.ui-tabs .ui-tabs-nav li {
list-style: none;
float: left;
position: relative;
top: 0;
margin: 1px .2em 0 0;
border-bottom-width: 0;
padding: 0;
white-space: nowrap;
}
.ui-tabs .ui-tabs-nav .ui-tabs-anchor {
float: left;
padding: .5em 1em;
text-decoration: none;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active {
margin-bottom: -1px;
padding-bottom: 1px;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
cursor: text;
}
.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
cursor: pointer;
}
.ui-tabs .ui-tabs-panel {
display: block;
border-width: 0;
padding: 1em 1.4em;
background: none;
}
.ui-tooltip {
padding: 8px;
position: absolute;
z-index: 9999;
max-width: 300px;
-webkit-box-shadow: 0 0 5px #aaa;
box-shadow: 0 0 5px #aaa;
}
body .ui-tooltip {
border-width: 2px;
}

File diff suppressed because one or more lines are too long

410
website/agenda/css/jquery-ui.theme.css vendored Normal file
View File

@@ -0,0 +1,410 @@
/*!
* jQuery UI CSS Framework 1.11.4
* http://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* http://api.jqueryui.com/category/theming/
*
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
*/
/* Component containers
----------------------------------*/
.ui-widget {
font-family: Verdana,Arial,sans-serif;
font-size: 1.1em;
}
.ui-widget .ui-widget {
font-size: 1em;
}
.ui-widget input,
.ui-widget select,
.ui-widget textarea,
.ui-widget button {
font-family: Verdana,Arial,sans-serif;
font-size: 1em;
}
.ui-widget-content {
border: 1px solid #aaaaaa;
background: #ffffff url("images/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
color: #222222;
}
.ui-widget-content a {
color: #222222;
}
.ui-widget-header {
border: 1px solid #aaaaaa;
background: #cccccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;
color: #222222;
font-weight: bold;
}
.ui-widget-header a {
color: #222222;
}
/* Interaction states
----------------------------------*/
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default {
border: 1px solid #d3d3d3;
background: #e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;
font-weight: normal;
color: #555555;
}
.ui-state-default a,
.ui-state-default a:link,
.ui-state-default a:visited {
color: #555555;
text-decoration: none;
}
.ui-state-hover,
.ui-widget-content .ui-state-hover,
.ui-widget-header .ui-state-hover,
.ui-state-focus,
.ui-widget-content .ui-state-focus,
.ui-widget-header .ui-state-focus {
border: 1px solid #999999;
background: #dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;
font-weight: normal;
color: #212121;
}
.ui-state-hover a,
.ui-state-hover a:hover,
.ui-state-hover a:link,
.ui-state-hover a:visited,
.ui-state-focus a,
.ui-state-focus a:hover,
.ui-state-focus a:link,
.ui-state-focus a:visited {
color: #212121;
text-decoration: none;
}
.ui-state-active,
.ui-widget-content .ui-state-active,
.ui-widget-header .ui-state-active {
border: 1px solid #aaaaaa;
background: #ffffff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
font-weight: normal;
color: #212121;
}
.ui-state-active a,
.ui-state-active a:link,
.ui-state-active a:visited {
color: #212121;
text-decoration: none;
}
/* Interaction Cues
----------------------------------*/
.ui-state-highlight,
.ui-widget-content .ui-state-highlight,
.ui-widget-header .ui-state-highlight {
border: 1px solid #fcefa1;
background: #fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;
color: #363636;
}
.ui-state-highlight a,
.ui-widget-content .ui-state-highlight a,
.ui-widget-header .ui-state-highlight a {
color: #363636;
}
.ui-state-error,
.ui-widget-content .ui-state-error,
.ui-widget-header .ui-state-error {
border: 1px solid #cd0a0a;
background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;
color: #cd0a0a;
}
.ui-state-error a,
.ui-widget-content .ui-state-error a,
.ui-widget-header .ui-state-error a {
color: #cd0a0a;
}
.ui-state-error-text,
.ui-widget-content .ui-state-error-text,
.ui-widget-header .ui-state-error-text {
color: #cd0a0a;
}
.ui-priority-primary,
.ui-widget-content .ui-priority-primary,
.ui-widget-header .ui-priority-primary {
font-weight: bold;
}
.ui-priority-secondary,
.ui-widget-content .ui-priority-secondary,
.ui-widget-header .ui-priority-secondary {
opacity: .7;
filter:Alpha(Opacity=70); /* support: IE8 */
font-weight: normal;
}
.ui-state-disabled,
.ui-widget-content .ui-state-disabled,
.ui-widget-header .ui-state-disabled {
opacity: .35;
filter:Alpha(Opacity=35); /* support: IE8 */
background-image: none;
}
.ui-state-disabled .ui-icon {
filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
}
/* Icons
----------------------------------*/
/* states and images */
.ui-icon {
width: 16px;
height: 16px;
}
.ui-icon,
.ui-widget-content .ui-icon {
background-image: url("images/ui-icons_222222_256x240.png");
}
.ui-widget-header .ui-icon {
background-image: url("images/ui-icons_222222_256x240.png");
}
.ui-state-default .ui-icon {
background-image: url("images/ui-icons_888888_256x240.png");
}
.ui-state-hover .ui-icon,
.ui-state-focus .ui-icon {
background-image: url("images/ui-icons_454545_256x240.png");
}
.ui-state-active .ui-icon {
background-image: url("images/ui-icons_454545_256x240.png");
}
.ui-state-highlight .ui-icon {
background-image: url("images/ui-icons_2e83ff_256x240.png");
}
.ui-state-error .ui-icon,
.ui-state-error-text .ui-icon {
background-image: url("images/ui-icons_cd0a0a_256x240.png");
}
/* positioning */
.ui-icon-blank { background-position: 16px 16px; }
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -96px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-on { background-position: -96px -144px; }
.ui-icon-radio-off { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
/* Misc visuals
----------------------------------*/
/* Corner radius */
.ui-corner-all,
.ui-corner-top,
.ui-corner-left,
.ui-corner-tl {
border-top-left-radius: 4px;
}
.ui-corner-all,
.ui-corner-top,
.ui-corner-right,
.ui-corner-tr {
border-top-right-radius: 4px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-left,
.ui-corner-bl {
border-bottom-left-radius: 4px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-right,
.ui-corner-br {
border-bottom-right-radius: 4px;
}
/* Overlays */
.ui-widget-overlay {
background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
opacity: .3;
filter: Alpha(Opacity=30); /* support: IE8 */
}
.ui-widget-shadow {
margin: -8px 0 0 -8px;
padding: 8px;
background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
opacity: .3;
filter: Alpha(Opacity=30); /* support: IE8 */
border-radius: 8px;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,650 @@
/*
include in your web page:
<link rel="stylesheet" type="text/css" media="screen" href="http://piradio.de/agenda_files/css/calcms.css" />
*/
/* calcms - common */
body{
text-align:left;
font: 1em/1.2em Ubuntu,"Lucida Grande",Verdana,Helvetica,Arial,sans-serif;
}
a{
text-decoration:none;
color:black;
}
a:visited{
color:black;
}
@media only screen and (max-device-width: 480px) {
#content{
width:480px;
}
}
@media only screen and (max-device-width: 800px) {
#content{
width:800px;
}
}
#content{
width:460px;
padding:10px;
}
pre{
text-align:left;
font-family:Courier;
padding:1em;
margin:1em;
border:1px solid black;
}
/* hide microformats */
.dtstart{
display:none;
visibility:hidden;
}
.dtend{
display:none;
visibility:hidden;
}
/* end of common */
/* menu */
#calcms_menu{
padding-top:3px;padding-right:5px;
margin-bottom:1px;
text-align:left;
clear:both;
line-height:120%;
/*padding:3px;*/
/*font-family:Verdana,Arial,sans-serif;*/
/*overflow:auto;*/
}
#calcms_menu li.leaf{
list-style-type:none;
list-style-image:url();
background:none;
padding:0;
}
/*
#calcms_menu a{
text-decoration:none;
}
*/
#calcms_menu a:hover,
#calcms_calendar a:hover{
text-decoration:underline;
}
#calcms_menu .date{
margin:0px;
font-weight:bold;
margin-top:1em;
margin-bottom:6px;
-moz-border-radius-topleft:12px;
-moz-border-radius-topright:12px;
-webkit-border-top-right-radius: 12px;
-webkit-border-top-left-radius: 12px;
}
#calcms_menu .title{
padding:0px;
margin:0px;
text-align:left;
}
/*
div:first-line #calcms_menu .title {
margin-left:0px;
}
*/
#calcms_menu .excerpt{
padding:3px;
margin:0px;
}
#calcms_menu .content{
padding:3px;
margin:0px;
clear:left;
margin:0
}
#calcms_menu .content p{
margin-top:10px
}
#calcms_menu .content h1{
text-align:left;
font-size:1.5em;
clear:left;
margin-top:16px
}
#calcms_menu .content h2{
text-align:left;
font-size:1.5em;
clear:left;
margin-top:16px
}
#calcms_menu .content h3{
text-align:left;
font-size:1.5em;
clear:left;
margin-top:16px
}
#calcms_menu .content h4{
text-align:left;
font-size:1.5em;
clear:left;
margin-top:16px
}
#calcms_menu li{
clear:left;
line-height:1.2em;
}
#calcms_menu .date{
margin-top:12px;
margin-left:3em;
clear:both;
}
#calcms_list .summary .title{
font-weight:bold;
}
#calcms_list .title{
margin-bottom:1em;
}
#calcms_list hr{
/*margin-bottom:2em;*/
background-color:#ddd;
}
#calcms_list .content img{
text-align:left;
font-size:1.5em;
margin-bottom:20px;
border:0;
/*
clear:both;
float:left;
margin-right:30px;
*/
float: right;
margin-left: 1em;
}
#calcms_list li{
/*
list-style-type:none;
list-style-image:url();
background:none;
padding:0;
*/
}
#calcms_playlist{
padding:1px;
margin:0px;
clear:both;
/*text-align:center;*/
}
#calcms_playlist div{
vertical-align:middle;
clear:both;
}
#calcms_playlist img{
width:2em;
height:2em;
margin:6px;
float:left;
opacity:0.9;
}
#calcms_playlist img:hover{
opacity:1.0;
}
#calcms_menu div{
vertical-align:middle;
clear:both;
}
#calcms_menu .event{
opacity:0.8;
}
/*
#calcms_menu .event:hover{
opacity:1.0;
}
*/
#calcms_menu img{
width:2em;
height:2em;
margin-right:6px;
margin-bottom:12px;
float:left;
}
#calcms_menu img:hover{
}
#calcms_playlist a{
clear:both;
float:none;
}
#calcms_menu .event{
padding:1px;
margin:0px;
clear:both;
text-align:left;
}
#calcms_menu .event.running{
font-weight:bold;
}
/* end of menu */
/* calcms_list */
div#calcms_list{
}
#content div a img,
#icon_bar a img,
{
margin:6px;
}
#calcms_list .date{
/*padding:6px;*/
/*margin:0px;*/
font-weight:bold;
margin-top:1em;
/*
-moz-border-radius-topleft:12px;
-moz-border-radius-topright:12px;
-webkit-border-top-right-radius: 12px;
-webkit-border-top-left-radius: 12px;
*/
}
#calcms_list .excerpt{
margin-left:40px;
margin-top:6px;
/*margin-bottom:10px;*/
/* color:#eee; */
}
#calcms_list .event.running{
/*padding:6px;*/
/*background: white;*/
/*border:1px solid #bbb;*/
color:#000;
}
#calcms_list .submitted{
position:absolute;
right:0px;
}
/* end of calcms_list */
/* calcms comments */
#calcms_comments .author{
color:#666;
font-weight:bold;
float:left;
}
#calcms_comments .date{
color:#888;
font-weight:normal;
margin:0;
padding:0;
}
#calcms_comments .content{
/* color:#ccc; */
font-weight:normal;
}
#calcms_comments .comment{
margin:0;
padding:0;
}
#calcms_comments .level0{
padding-top:1.5em;
margin-left:00px;
}
#calcms_comments .level1{
margin-left:20px;
}
#calcms_comments .level2{
margin-left:40px;
}
#calcms_comments .level3{
margin-left:60px;
}
#calcms_comments .level4{
margin-left:80px;
}
#calcms_comments .level5{
margin-left:100px;
}
#calcms_comments .level6{
margin-left:120px;
}
#calcms_comments .level7{
margin-left:140px;
}
#calcms_comments .level8{
margin-left:160px;
}
#calcms_comments .level9{
margin-left:180px;
}
#calcms_comments .level10{
margin-left:200px;
}
#calcms_add_comment{
visibility:hidden;
display:none;
}
#calcms_newest_comments .author{
font-weight:bold;
}
#calcms_newest_comments li,
#calcms_newest_comments li.leaf{
list-style-type:none;
list-style-image:url();
background:none;
}
#calcms_newest_comments span.content{
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
-icab-text-overflow: ellipsis;
-khtml-text-overflow: ellipsis;
-moz-text-overflow: ellipsis;
-webkit-text-overflow: ellipsis;
}
#calcms_newest_comments li.leaf a,
#calcms_newest_comments li.leaf span{
line-height:1.2em;
}
#calcms_newest_comments li.leaf a:hover{
text-decoration:none;
}
/* end of calcms comments*/
/* calcms_search */
#calcms_search{
margin:0;
z-index:3;
text-align:left;
font-size:10px;
clear:both;
}
#calcms_search input{
width:80px;
}
table#calcms_search{
padding:0;
margin:0;
text-align:left;
}
table#calcms_search td a{
padding:1px;
}
#calcms_search input#calcms_search_field,
#calcms_search select{
width:100px;
}
#calcms_search input#calcms_search_field{
float:left;
}
#calcms_search form{
float:left;
}
/* end of calcms_search */
/* calcms_calendar */
#calcms_calendar{
overflow:auto;
text-align:center;
padding:0px;
margin:0px;
vertical-align:top;
clear:both;
width:100%;
}
#calcms_calendar .week_1,
#calcms_calendar .week_2,
#calcms_calendar .week_3,
#calcms_calendar .week_4,
#calcms_calendar .week_5{
}
#calcms_calendar th{
margin:0px;
font-weight:normal;
margin-top:1em;
}
#calcms_calendar th a{
/* color:#AEB1B3; */
}
/* selected fields */
#calcms_calendar .selected, .night, .morning, .noon, .afternoon, .evening{
background:#eee;
font-size:bold;
font-weight:bold;
}
#calcms_calendar table{
text-align:center;
padding:0px;
margin:0px;
}
/* hover effects */
#calcms_calendar table td:hover{
background-color:#f0f0f0;
}
#calcms_calendar table td{
border-bottom:1px solid #D1C7CA;
opacity:0.8;
/*border-right:1px solid #D1C7CA;*/
}
#calcms_calendar table td.selected{
/*opacity:1.0;*/
}
#calcms_calendar table td.selected:hover{
background-color:#f0f0f0;
border-top: 1px solid #D1C7CA;
border-bottom:1px solid #D1C7CA;
}
#calcms_calendar table a{
text-decoration:none;
font-weight:normal;
}
#calcms_calendar table td.selected a{
font-weight:bold;
}
#calcms_calendar td,
#calcms_calendar th{
padding:0px;
padding-left:1em;
padding-right:1em;
padding-bottom:1em;
margin:0;
text-align:center;
}
#calcms_calendar th.first,
#calcms_calendar th.last{
font-size:large;
}
/* not selectable columns */
#calcms_calendar table td.row_type:hover{
border-bottom:1px solid #D1C7CA;
border-right: 1px solid #D1C7CA;
background-color:#ffffff;
}
#calcms_calendar .row_type{
/* width:100px
*/
}
.calcms_today{
font-weight:bold;
}
/* end of calcms_calendar */
.blnfm, .multicultfm, .ohrfunk, .twenfm, .offenerkanalberlin, .klubradio, .piradio,
.studioansage, .studiolottumstrasse, .studiorebootfm
{
/*
border-radius: 12px;
-moz-border-radius: 12px;
-webkit-border-radius: 12px;
*/
padding:6px;
margin:6px;
}
.blnfm{
background-color:white;
}
.multicultfm{
background-color:white;
}
.ohrfunk{
background-color:white;
}
.twenfm{
background-color:white;
}
.offenerkanalberlin{
background-color:white;
}
.klubradio{
background-color:white;
}
.piradio{
background-color:white;
}
/*Einheitsradio */
.studiolottumstrasse{
background-color:white;
/* background-color:#ffddff; */
}
.studioansage{
background-color:white;
/* background-color:#ddffdd; */
}
.studiorebootfm{
background-color:white;
/* background-color:#ffff00; */
}
.feed-icon{
float:left;
}
#icon_bar{
padding-bottom:6px;
}
#icon_bar .feed-icon{
height:24px;
}
#icon_bar .feed-icon img{
margin:6px;
text-align:right;
}
input{
width:200px;
}
.vevent a{
font-weight:normal;
}
div#jp_player_1{
text-decoration:none;
height:24px;
padding-left:30px;
color:black;
background-repeat:no-repeat;
background-image:url("/agenda/image/player4.play.png");
border:1px solid black;
}
div#jp_equalizer_1{
width:0px;
height:2px;
background:#ccc;
border:1px solid gray;
}

48
website/agenda/events.cgi Executable file
View File

@@ -0,0 +1,48 @@
#! /usr/bin/perl -w
use warnings "all";
#no warnings 'redefine';
#use diagnostics;
use strict;
use Data::Dumper;
#use utf8;
use DBI;
use CGI qw(header param Vars);
$CGI::POST_MAX = 1000;
$CGI::DISABLE_UPLOADS = 1;
use params;
use config;
use log;
use events;
use time;
#binmode STDOUT, ":utf8";
binmode STDOUT, ":encoding(UTF-8)";
my $r=shift;
(my $cgi, my $params, my $error)=params::get($r);
if ($0=~/events.*?\.cgi$/){
#my $cgi=new CGI();
#my %params=$cgi->Vars();
our $config=config::get('config/config.cgi');
$params->{recordings}=1 if $params->{template}=~/events_playout/;
my $request={
url => $ENV{QUERY_STRING},
params => {
original => $params,
checked => events::check_params($config, $params),
},
};
#events::init($request);
log::init($request);
my $output='';
events::get_cached_or_render($output, $config, $request);
print $output."\n";
}
1;

BIN
website/agenda/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,10 @@
Options -Indexes +FollowSymLinks +MultiViews -ExecCGI
#Order allow,deny
#allow from all
Require all granted
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 10 minutes"
</IfModule>

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

26
website/agenda/index.html Normal file
View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html> <head>
<title>calcms</title> <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1">
<meta charset="utf-8"> <meta http-equiv="Cache-Control" content="no-cache">
<link rel="stylesheet" href="/css/style.css"> <!--calcms start-->
<link rel="alternate" type="application/atom+xml" title="Sendeplan Atom" href="/agenda/atom/" /> <link rel="alternate" type="application/rss+xml" title="Sendeplan RSS" href="/agenda/rss/" />
<link rel="alternate" type="application/atom+xml" title="Sendekommentare" href="/agenda/feed_kommentare/" /> <link rel="stylesheet" type="text/css" media="screen" href="/agenda/css/calcms.css" />
<script type="text/javascript" src="/agenda/js/jquery.min.js"></script> <script type="text/javascript" src="/agenda/js/calcms.js"></script>
<script type="text/javascript" src="/agenda/js/calcms.cust.js"></script> <!--calcms end--></head> <body>
<div id="container"> <header id="header">
<h1><a href="/">calcms</a></h1> </header>
<nav id="nav-main"> <ul>
<li> <a href="/">home</a></li> <li>
<a href="/agenda/programm.html">schedule</a> </li>
<li> <a href="/agenda/planung/">editor</a></li> <li>
<a href="/download.html">download</a> </li></ul> </nav>
<div id="content"> <article ><!-- include daily schedule with excerpt --> <div id="calcms_list" class="content">bitte warten</div></article> <aside class="left">
<center> <h2>Programm</h2>
<div class="content"> <!-- include short list of schedules -->
<div id="calcms_menu">bitte warten...</div> </div>
<h2>Kommende Sendung</h2> <div class="content"><!-- show coming shows --> <div id="calcms_playlist">bitte warten…</div></div> </center></aside> <aside class="right">
<center> <h2>Kalender</h2>
<div class="content"> <!-- show calendar -->
<div id="calcms_calendar">bitte warten...</div> </div>
<h2>Suche</h2> <div class="content"><!-- calcms search start --><div id="calcms_search"><input id="calcms_search_field" name="search" value="" /><input value="suchen" onclick="calcms.selectSearchEventListener();return false;" type="button" /><a id="calcms_search_show_details" href="#" onclick="calcms.showAdvancedSearch('calcms_enhanced_search');return false;">erweitert</a><br /> <div id="calcms_enhanced_search" style="display: none;">Archiv <input type="checkbox" name="calcms_archive" id="calcms_archive" /><span id="calcms_categories"></span><span id="calcms_series_names"></span><span id="calcms_programs"></span></div> </div><!-- calcms search end --> </div></center> </aside></div> <footer>calcms 2010 - 2017 by <a href="http://radiopiloten.de">http://radiopiloten.de</a></footer> </div></body> </html>

View File

@@ -0,0 +1,4 @@
#!/bin/perl
print "Content-type:text/plain\n\nCurrent IP Address:".$ENV{REMOTE_ADDR}."\n";

View File

@@ -0,0 +1,17 @@
Options -Indexes +FollowSymLinks +MultiViews -ExecCGI
#Order allow,deny
#allow from all
Require all granted
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 10 minutes"
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(jpg|jpeg|png|gif|js|css|swf)$">
# Header set Cache-Control "public"
Header set Cache-Control "max-age=600, public"
</FilesMatch>
</IfModule>

View File

@@ -0,0 +1,403 @@
var calcms_settings = new Array();
(function($, calcms) {
// show current project
calcms.selectProject = function selectProject() {
var project = calcms.getProject();
console.log("project=" + project)
calcms.clearOnChangeArchive();
calcms.showProjectCategories(project);
calcms.showProjectSeriesNames(project);
calcms.selectFirstOption('#calcms_series_name_'
+ calcms.getJsName(project));
calcms.selectFirstOption('#calcms_category_'
+ calcms.getJsName(project));
}
// search events
calcms.selectSearchEventListener = function selectSearchEventListener() {
var project = calcms.getProject();
calcms.showSearchResultsByProject(project, calcms.getSearchElement()
.val(), calcms.isArchive());
calcms.selectFirstOption('#calcms_series_name_'
+ calcms.getJsName(project));
calcms.selectFirstOption('#calcms_category_'
+ calcms.getJsName(project));
calcms.registerOnChangeArchive(function() {
calcms.showSearchResultsByProject(project, calcms
.getSearchElement().val(), calcms.isArchive());
});
}
// show events for selected category of project
calcms.selectCategory = function selectCategory(project, category) {
calcms.showEventsByProjectAndCategory(project, category, calcms
.isArchive());
calcms.selectFirstOption('#calcms_series_name_'
+ calcms.getJsName(project));
calcms.resetSearch();
calcms.registerOnChangeArchive(function() {
calcms.showEventsByProjectAndCategory(project, category, calcms
.isArchive());
});
}
// show events for selected series of project
calcms.selectSeries = function selectSeries(project, seriesName) {
calcms.showEventsByProjectAndSeriesName(project, seriesName, calcms
.isArchive());
calcms.selectFirstOption('#calcms_category_'
+ calcms.getJsName(project));
calcms.resetSearch();
calcms.registerOnChangeArchive(function() {
calcms.showEventsByProjectAndSeriesName(project, seriesName, calcms
.isArchive());
});
}
// calendar events
calcms.selectMonthEventListener = function selectMonthEventListener(month) {
calcms.showCalendarAndEventsByMonth(month);
}
calcms.selectWeekdayEventListener = function selectWeekdayEventListener(
start_date, end_date, weekday) {
calcms.showEventsByWeekday(start_date, end_date, weekday);
}
calcms.selectDateRangeEventListener = function selectDateRangeEventListener(
from, till) {
calcms.showEventsByDateRange(from, till);
}
calcms.selectDateEventListener = function selectDateEventListener(date) {
calcms.showEventsByDate(date);
}
// initial initialize
function initCalcms() {
calcms.set('base_url', '');
calcms.set('calendar_url', '/agenda/kalender');
calcms.set('menu_url', '/agenda/menu');
calcms.set('events_url', '/agenda/sendungen');
calcms.set('list_url', '/agenda/sendung');
calcms.set('next_series_url', '/programm/sendung/serie_plus');
calcms.set('prev_series_url', '/programm/sendung/serie_minus');
calcms.set('ical_url', '/agenda/ical');
calcms.set('feed_url', '/agenda/feed/');
calcms.set('playlist_url', '/agenda/playlist/');
calcms.set('search_url', '/agenda/suche/');
calcms.set('search_category_url', '/agenda/kategorie/');
calcms.set('search_series_name_url', '/agenda/sendereihe/');
calcms.set('category_url', '/agenda/kategorien/');
calcms.set('series_name_url', '/agenda/sendereihen/');
calcms.set('comments_url', '/agenda/kommentare/');
calcms.set('add_comment_url', '/agenda/kommentar_neu/');
calcms.set('newest_comments_url', '/agenda/neueste_kommentare/');
return true;
}
var loadedSearchComponents = 0;
// load projects, series and categories and show search fields
// remove empty projects if both series and categories have been loaded
calcms.showAdvancedSearch = function showAdvancedSearch(id) {
searchReady = 0;
var element = $('#calcms_enhanced_search');
if (element.length == 0)
return;
if (element.css('display') == 'none') {
var url = calcms.get('category_url');
calcms.updateContainer('calcms_categories', url, 1, function() {
calcms.selectProject();
loadedSearchComponents++;
if (loadedSearchComponents == 2) {
calcms.removeEmptyProjects();
}
});
url = calcms.get('series_name_url');
calcms.updateContainer('calcms_series_names', url, 1, function() {
calcms.selectProject();
loadedSearchComponents++;
if (loadedSearchComponents == 2) {
calcms.removeEmptyProjects();
}
});
} else {
calcms.showProjectCategories(calcms.getProject());
calcms.showProjectSeriesNames(calcms.getProject());
}
$("#" + id).slideToggle();
}
calcms.insertDeskNextShows = function insertDeskNextShows(desk) {
var url = '/agenda/suche/all/' + desk + '/kommende/';
calcms.updateContainer('showDesk', url, 1);
return false;
}
calcms.insertDeskPrevShows = function insertDeskPrevShows(desk) {
var url = '/agenda/suche/all/' + desk + '/vergangene/';
calcms.updateContainer('showDesk', url, 1);
return false;
}
function insertDeskDetails() {
var pattern = new RegExp(/redaktion\/(.*)$/);
var matchs = pattern.exec(document.location.href);
if ((matchs != null) && (matchs.length > 0) && (matchs[1] != '')) {
var desk = $('#center h2:first').text();
desk = desk.replace('Redaktion: ', '');
desk = escape(desk);
$('#center .content').append(
'<div>' + '<a onclick="insertDeskPrevShows(\'' + desk
+ '\');return false;" href="#">«letzte«</a>'
+ ' Sendungen '
+ '<a onclick="insertDeskNextShows(\'' + desk
+ '\');return false;" href="#">»nächste»</a>'
+ '<div id="showDesk" />' + '</div>');
}
}
function fixBlogEntries() {
if (document.location.href.match('/redaktionen/')
|| document.location.href.match('/redaktionen?')
|| document.location.href.match('/redaktionen$')) {
$('img.image-thumbnail').css('width', '3em');
$('img.image-thumbnail').css('height', '3em');
$('div.image-attach-teaser').css('width', '3em');
$('div.node').css('padding', '0');
$('div.node').css('margin', '0');
$('#center .submitted').remove();
$('#center .clear-block h2 a')
.each(
function(index) {
$(this)
.html(
$(this)
.text()
.replace('Redaktion: ',
'<font color="gray">Redaktion:</font> '));
if ($(this).text().match(/Information:/))
$(this).remove();
})
}
}
function setImageSize() {
var image = '#calcms_list div.content img';
var size = $(window).width();
size = Math.floor(size * 0.16);
$(image).css('width', size + 'px');
$(image).css('height', size + 'px');
if (size > 200) {
$(image).each(function(index) {
var url = $(this).attr('src');
if (url != null) {
url = url.replace('/thumbs/', '/images/');
console.log(url);
$(this).attr('src', url);
}
});
} else {
$(image).each(function(index) {
var url = $(this).attr('src');
if (url != null) {
url = url.replace('/images/', '/thumbs/');
$(this).attr('src', url);
}
});
}
}
function setThumbs() {
$('#calcms_playlist img').each(function(index) {
var url = $(this).attr('src');
if (url != null) {
url = url.replace('/images/', '/thumbs/');
$(this).attr('src', url);
}
});
}
function addCommentsOnAgendaPages() {
if (calcms.contains(window.location.href, '/programm/')
|| calcms.contains(window.location.href, '/agenda/')) {
$('#sidebar-right')
.append(
'<div id="block-block-2" class="clear-block block block-block"><h2>Kommentare</h2><div class="content">'
+ '<div id="calcms_newest_comments">Bitte warten…</div>'
+ '</div></div>');
}
}
function scrollNextEvent() {
if ($('#calcms_running_event').length == 0)
return;
$('#playlist_container').scrollLeft(0);
setInterval(nextSlideEvent, 10000);
}
var numberOfComingShows = 100;
var slideCount = 0;
var slideOffset = 1;
var slideEvents = 1;
// slideEvents will be updated at onmouseenter/leave handler at
// playlist_long
function nextSlideEvent() {
if (slideEvents == 0)
return;
if ($('#coming_shows a').length == 0)
return;
if (slideCount == 0) {
numberOfComingShows = $('#coming_shows a').length;
$('#playlist_container').scrollLeft(0)
$('#playlist_container').css('overflow', 'auto');
$('#playlist_container').css('-webkit-overflow-scrolling', 'touch');
$('#playlist_container').css('height', '150');
$('#coming_shows').css('white-space', 'nowrap');
$('#coming_shows').css('overflow-x', 'hidden');
$('#coming_shows').css('height', '150');
}
// console.log(slideCount+" "+slideOffset)
$('#playlist_container').animate({
scrollLeft : slideCount * 115 + "px"
}, 5000);
if (slideCount < 0)
slideOffset = 1
if (slideCount > numberOfComingShows + 1 - $('#coming_shows').width()
/ 100)
slideOffset = -1
slideCount += slideOffset;
}
function mobilise() {
if (!navigator.userAgent.match(/Mobi/))
return;
$('#wrapper #container #sidebar-left').before(
$('#wrapper #container #center'));
$('#wrapper #container #sidebar-left').before(
$('#wrapper #container #sidebar-right'));
$('body.sidebars').css('min-width', '100%');
$('body.sidebar-left').css('min-width', '100%');
$('body.sidebar-right').css('min-width', '100%');
$('#wrapper #container .sidebar').css('width', '100%');
$('#wrapper #container').css('width', '100%');
$('#wrapper #container').css('max-width', '100%');
$('#wrapper #container').css('margin', '0');
$('#wrapper #container').css('padding', '0');
$('#center').css('margin', '0');
$('#center #squeeze').css('margin', '0');
$('#center *').css('margin-left', '0');
$('#center *').css('margin-right', '0');
$('#center .right-corner').css('position', 'static');
$('#center .right-corner').css('left', '0');
$('#center .right-corner').css('padding-left', '0');
$('#center .right-corner').css('padding-right', '0');
$('#center .right-corner').css('background-image', 'url()');
$('#center .left-corner').css('position', 'static');
$('#center .left-corner').css('padding-left', '0');
$('#center .left-corner').css('padding-right', '0');
$('#center .left-corner').css('background-image', 'url()');
$('#center *').css('background-image', 'url()');
$('#wrapper #container #header').css('height', '100px');
var padding = '0.5em'
$('#center .left-corner').css('padding-left', padding);
$('#center .left-corner').css('padding-right', padding);
$('#wrapper #container #sidebar-left').css('padding-left', padding);
$('#wrapper #container #sidebar-left').css('padding-right', padding);
// $('*').css('background','none');
// $('#sidebar-left div.content').css('text-align','center');
// $('#sidebar-left *').css('margin-left','0');
// $('#sidebar-left *').css('margin-right','0');
// $('#sidebar-right *').css('margin-left','0');
// $('#sidebar-right *').css('margin-right','0');
// $('#sidebar-left').css('width','90%');
$('.node').css('padding-left', '0');
$('.node').css('padding-right', '0');
$('#calcms_search input').css("padding", "1em");
$('#calcms_search select').css("padding", "1em");
var menu = "ul.links.primary-links";
$(menu).addClass('mobileMenu');
$(menu).before('<div id="mobileMenuButton"></div>');
$(menu).hide();
var menu2 = "ul.links.secondary-links";
$(menu2).each(function() {
$(menu).append($(this).html());
})
$(menu2).remove();
$('#calcms_calendar table').css('width', '90%');
// move footer down
var footer = $('#wrapper #footer').html();
$('body').append(footer);
$('#wrapper #footer').remove();
$("#mobileMenuButton").click(function() {
$(menu).slideToggle();
return false;
});
}
function initSearch() {
var base = $('#calcms_search_show_details');
var elem = $('#calcms_search_show_details #plus');
if (elem.length == 0) {
base.append('<span id="plus"> ▼ </span>');
base.prepend('<span id="plus"></span>');
}
}
function initAll() {
initCalcms();
addCommentsOnAgendaPages();
calcms.showPlaylist();
calcms.showNewestComments();
// insertDeskDetails();
// fixBlogEntries();
calcms.removeCurrentPlayingHeader();
// setImageSize();
// setThumbs();
// scrollNextEvent();
// mobilise();
initSearch();
console.log("calcms inited")
}
$(document).ready(function() {
initAll();
});
}(jQuery, calcms));

File diff suppressed because one or more lines are too long

790
website/agenda/js/calcms.js Normal file
View File

@@ -0,0 +1,790 @@
var calcms = (function($) {
// define this
var my = {};
// calcms base functions
// event handlers are customized at herbstradio.org
my.updateContainer = function updateContainer(id, url, onLoading, callback) {
if (id == null)
return;
if ($("#" + id).length == 0)
return;
// if (onLoading)document.getElementById(id).innerHTML="lade ...";
$("#" + id).load(url, null, callback);
}
my.load = function load(url) {
window.location.href = url;
// $(window).load(url);
// $('html').load(url);
}
my.postContainer = function postContainer(url, parameters, callback) {
if (url != '')
$.post(url, parameters, callback);
}
// get calcms setting
my.get = function get(name) {
if (calcms_settings[name] == null)
return '';
return calcms_settings[name];
}
// set calcms setting
my.set = function set(name, value) {
calcms_settings[name] = value;
}
// get select box value
my.selectValue = function selectValue(element) {
value = element.options[element.selectedIndex].value;
return value;
}
my.selectFirstOption = function selectFirstOption(id) {
if ($(id) && $(id).length > 0)
$(id)[0].selectedIndex = 0;
}
my.contains = function contains(s, t) {
if (s == false)
return false;
if (t == false)
return false;
return s.indexOf(t) != -1;
}
my.getJsName = function getJsName(s) {
s = s.replace(/[^a-zA-Z\_0-9]/g, '_');
s = s.replace(/_+/g, '_');
return s;
}
my.isArchive = function isArchive() {
if ($('#calcms_archive:checked').length == 0)
return 0;
return 1;
}
my.getSearchElement = function getSearchElement() {
return $("#calcms_search input[name='search']");
}
my.resetSearch = function resetSearch() {
$("#calcms_search_field").val('');
}
// set calcms_settings to parameters from URL
my.evaluateParametersFromUrl = function evaluateParametersFromUrl() {
var location = new String(window.location);
if (!location.match(my.get("base_url")))
return;
if (window.location.search != "") {
var parameters = window.location.search.split("?")[1].split("&");
for (var i = 0; i < parameters.length; i++) {
var pair = parameters[i];
var name_values = pair.split("=");
if (name_values != null) {
// alert(name_values[0]+"="+name_values[1]);
// set(name_values[0],name_values[1]);
var element = document.getElementById(name_values[0]);
if (element != null)
element.value = name_values[1];
}
}
}
var sendung = /\/sendung\/(\d+)\//;
sendung.exec(location);
if (RegExp.$1 != null && RegExp.$1 != '') {
// alert(RegExp.$1);
set('event_id', RegExp.$1);
set('last_event_id', my.get('event_id'));
} else {
var sendungen = /\/sendungen\/(\d{4}\-\d{2}\-\d{2})\/(\d{4}\-\d{2}\-\d{2})\/(\d)\//;
sendungen.exec(location);
if (RegExp.$1 != '' && RegExp.$2 != '' && RegExp.$3 != '') {
set('from_date', RegExp.$1);
set('till_date', RegExp.$2);
set('weekday', RegExp.$3);
} else {
var sendungen = /\/sendungen\/(\d{4}\-\d{2}\-\d{2})\/(\d{4}\-\d{2}\-\d{2})\//;
sendungen.exec(location);
if (RegExp.$1 != '' && RegExp.$2 != '') {
set('from_date', RegExp.$1);
set('till_date', RegExp.$2);
} else {
var sendungen = /\/sendungen\/(\d{4}\-\d{2}\-\d{2})\//;
sendungen.exec(location);
if (RegExp.$1 != '') {
set('date', RegExp.$1);
}
}
}
var kalender = /\/kalender\/(\d{4}\-\d{2}\-\d{2})\/(\d{4}\-\d{2}\-\d{2})\//;
kalender.exec(location);
if (RegExp.$1 != '' && RegExp.$2 != '') {
set('from_date', RegExp.$1);
set('till_date', RegExp.$2);
} else {
var kalender = /\/kalender\/(\d{4}\-\d{2}\-\d{2})\//;
kalender.exec(location);
if (RegExp.$1 != '') {
set('date', RegExp.$1);
}
}
}
}
// return URL from calcms_settings
// parameters can be overwritten by field and value
// This handles main controller interaction logics
my.setAndGetUrlParameters = function setAndGetUrlParameters(field, value) {
// overwrite fields by field and value
if (field != null && value != null && field != '') {
// alert(target+" "+field+" "+value);
set(field, value);
}
// read fields
var debug = my.get('debug');
var from_date = my.get('from_date');
var till_date = my.get('till_date');
var date = my.get('date');
var month = my.get('month');
var weekday = my.get('weekday');
var time_of_day = '';
var time = '';
var program = my.get('program');
var series_name = my.get('series_name');
var category = my.get('category');
var tag = my.get('tag');
var search_field = my.get('search');
// delete filters by current action
if ((field == 'search' && search_field != '')
|| (field == 'category' && category != '')
|| (field == 'series_name' && series_name != '')
|| (field == 'program' && program != '') || (field == 'tag')
&& tag != '') {
weekday = '';
date = '';
from_date = '';
till_date = '';
}
if (field == 'search') {
category = '';
series_name = '';
program = '';
}
if (field == 'category') {
search_field = '';
series_name = '';
program = '';
}
if (field == 'program') {
search_field = '';
series_name = '';
category = '';
}
if (field == 'series_name') {
search_field = '';
program = '';
category = '';
}
if (field == 'month') {
if (month != '') {
from_date = month;
till_date = month.substring(0, month.length - 2) + "31";
}
weekday = '';
date = '';
category = '';
program = '';
series_name = '';
tags = '';
search_field = '';
}
if (field == 'week') {
weekday = '';
date = '';
category = '';
program = '';
series_name = '';
tags = '';
search_field = '';
}
if (field == 'weekday') {
/*
* if (month != ''){ from_date=month;
* till_date=month.substring(0,month.length-2)+"31" ; }
*/
category = '';
program = '';
series_name = '';
tags = '';
search_field = '';
}
if (field == 'date') {
weekday = '';
from_date = '';
till_date = '';
category = '';
program = '';
series_name = '';
tags = '';
search_field = '';
}
if (field == 'time') {
if (time == 'null') {
return
} else {
weekday = '';
time_of_day = '';
}
}
if (field == 'month' || field == 'week' || field == 'weekday'
|| field == 'time_of_day') {
time = '';
}
// build target URL
var url = '';
if (field == 'month' || field == 'week') {
if (from_date != '')
url += '/' + from_date;
if (till_date != '')
url += '/' + till_date;
} else if (weekday != '') {
if (from_date != '')
url += '/' + from_date;
if (till_date != '')
url += '/' + till_date;
url += '/' + weekday;
} else if (date != '') {
if (date == 'today') {
url += '/heute/';
} else {
url += '/' + date;
}
}
if (search_field != '') {
url += "/suche/" + search_field;
}
if (category != null && category != '') {
url += "/kategorie/" + category;
}
if (series_name != null && series_name != '') {
url += "/sendereihe/" + series_name;
}
if (url.substr(url.length - 1, url.length) != '/') {
url += '/';
}
if (time_of_day != '') {
url += "&time_of_day=" + time_of_day;
} else if (time != '' && time != 'null') {
url += "&" + time;
}
if (tag != null && tag != '') {
url += "&tag=" + tag;
}
if (program != null && program != '') {
url += "&program=" + program;
}
if (field == 'print') {
url += "&print=1";
}
if (debug != '') {
url += '&debug=' + debug;
}
return url;
}
// show current project categories
my.showProjectCategories = function showProjectCategories(project) {
var projectJsName = calcms.getJsName(project);
$('#calcmsCategoryForm select').each(function() {
var id = $(this).attr('id');
if (id == "calcms_category_" + projectJsName) {
if ($(this).css('display') == 'none')
$(this).show();
} else {
if ($(this).css('display') != 'none')
$(this).hide();
}
});
}
// show current series categories
my.showProjectSeriesNames = function showProjectSeriesNames(project) {
var projectJsName = calcms.getJsName(project);
$('#calcmsSeriesNamesForm select').each(function() {
var id = $(this).attr('id');
if (id == "calcms_series_name_" + projectJsName) {
if ($(this).css('display') == 'none')
$(this).show();
} else {
if ($(this).css('display') != 'none')
$(this).hide();
}
});
}
// get current project
my.getProject = function getProject() {
var project = $('#calcms_project');
if (project.length == 0)
return 'all';
return project.val();
}
// remove projects from form without categories and series_names
my.removeEmptyProjects = function removeEmptyProjects() {
$('#calcms_project option').each(
function() {
var project = $(this).val();
var hasCategories = $('#calcms_category_'
+ calcms.getJsName(project)).length;
var hasSeries = $('#calcms_series_name_'
+ calcms.getJsName(project)).length;
if ((hasCategories == 0) && (hasSeries == 0)) {
$(this).remove();
}
});
}
my.clearOnChangeArchive = function clearOnChangeArchive() {
$('#calcms_archive').off();
}
// register action on changing archive
my.registerOnChangeArchive = function registerOnChangeArchive(action) {
my.clearOnChangeArchive();
$('#calcms_archive').on('click', action);
}
// show all events for a given project
my.showSearchResultsByProject = function showSearchResultsByProject(
project, value, archive) {
if (value != null && value != '') {
var url = my.get('search_url');
if (project != '' && project != null)
url += escape(project) + '/';
else
url += 'all/';
if (value != '' && value != null)
url += escape(value) + '/';
if (archive != null && archive == 0)
url += 'kommende/';
if (archive != null && archive == 1)
url += 'vergangene/';
my.updateContainer('calcms_list', url, 1);
}
}
// show all events for a given category
my.showEventsByCategory = function showEventsByCategory(value) {
if (value != '' && value != null) {
my.updateContainer('calcms_list', my.get('search_category_url')
+ escape(value) + '/', 1);
}
}
// show all events for a given project and category
my.showEventsByProjectAndCategory = function showEventsByProjectAndCategory(
project, category, archive) {
if (category != '' && category != null) {
var url = my.get('search_category_url');
if (project != '' && project != null)
url += escape(project) + '/';
if (category != '' && category != null)
url += escape(category) + '/';
if (archive != null && archive == 0)
url += 'kommende/';
if (archive != null && archive == 1)
url += 'vergangene/';
my.updateContainer('calcms_list', url, 1);
}
}
// show all events for a given project and series
my.showEventsByProjectAndSeriesName = function showEventsByProjectAndSeriesName(
project, seriesName, archive) {
if (seriesName != '' && seriesName != null) {
var url = my.get('search_series_name_url');
if (project != '' && project != null)
url += escape(project) + '/';
if (seriesName != '' && seriesName != null)
url += escape(seriesName) + '/';
if (archive != null && archive == 0)
url += 'kommende/';
if (archive != null && archive == 1)
url += 'vergangene/';
my.updateContainer('calcms_list', url, 1);
}
}
// show all events for a given series
my.showEventsBySeriesName = function showEventsBySeriesName(value) {
if (value != '' && value != null) {
my.updateContainer('calcms_list', my.get('search_series_name_url')
+ escape(value) + '/', 1);
}
}
// show all events for a given program
my.showEventsByProgram = function showEventsByProgram(value) {
var events_url = my.get('events_url');
var url = my.setAndGetUrlParameters('program', value);
if (value != '' && value != null) {
// my.updateContainer('calcms_list', events_url+url, 1);
my.updateContainer('calcms_list', url, 1);
}
}
// show next event of a given series
my.showNextSeriesEvent = function showNextSeriesEvent(value) {
var events_url = my.get('next_series_url');
my.load(events_url + '/' + value + '.html');
}
// show previous event of a given series
my.showPrevSeriesEvent = function showPrevSeriesEvent(value) {
var events_url = my.get('prev_series_url');
my.load(events_url + '/' + value + '.html');
}
my.showMenuAndList = function showMenuAndList(target, field, value) {
var events_url = my.get('events_url');
var menu_url = my.get('menu_url');
var event_id = my.get('event_id');
var url = my.setAndGetUrlParameters(field, value);
if (target == 'window') {
window.location.href = events_url + url;
} else {
my.updateContainer('calcms_menu', menu_url + url, 1);
if (event_id != '' && event_id != null && Number(event_id) != 'NaN') {
// load list selected by url
my.showEvents(event_id, '');
my.set('event_id', '');
} else {
// load event list
my.updateContainer('calcms_list', events_url + url, 1);
my.set('last_list_url', events_url + url);
}
}
return false;
}
// load given event details into list
my.showEvents = function showEvents(event_id, view) {
if (view == null || view == '')
view = 'list_url';
if (event_id != '') {
var url = my.get(view) + '/' + event_id + '/';
my.updateContainer('calcms_list', url, 1);
} else {
document.getElementById('calcms_list').innerHTML = 'keine Sendung gefunden...';
}
}
// load given event details into list
my.showEvent = function showEvent(event_id) {
var old_url = my.get('last_list_url');
var url = my.get('list_url') + '/' + event_id + '/';
if (url != old_url) {
my.set('last_event_id', event_id);
my
.updateContainer(
'calcms_list',
url,
1,
function(responseText, textStatus, XMLHttpRequest) {
var back_link = '<a href="#" onclick="updateContainer(\'calcms_list\',\''
+ old_url
+ '\');return false;">zur&uuml;ck</a>';
document.getElementById('calcms_list').innerHTML = back_link
+ document
.getElementById('calcms_list').innerHTML
+ '<p><hr/>' + back_link;
});
}
}
// Calendar actions
// update menu and list by given date
my.showEventsByDate = function showEventsByDate(date) {
// my.set('date',date);
my.showMenuAndList('', 'date', date);
return false;
};
// update menu and list by events from weekday at given date range
my.showEventsByWeekday = function showEventsByWeekday(from, till, weekday) {
my.set('from_date', from);
my.set('till_date', till);
my.set('weekday', weekday);
my.showMenuAndList('', 'weekday');
return false;
};
// update menu and list by events from given date range
my.showEventsByDateRange = function showEventsByDateRange(from, till) {
my.set('from_date', from);
my.set('till_date', till);
my.showMenuAndList('', 'week');
return false;
};
// load calendar content
my.showCalendar = function showCalendar(target, field) {
var calendar_debug = my.get('calendar_debug');
var calendar_url = my.get('calendar_url');
var debug = my.get('debug');
var date = my.get('month');
var url = calendar_url;
if (field == 'month') {
url += '/' + date + '/';
}
if (debug != '') {
url += '&debug=' + debug;
}
if (target == 'window') {
window.location.href = events_url + url;
} else {
my.updateContainer('calcms_calendar', url);
}
if (calendar_debug != null) {
calendar_debug.innerHTML = url;
}
return false;
}
// update menu, list and calendar widget by entries of given month YYYY-MM
// (current day)
my.showTodaysCalendarAndEvents = function showTodaysCalendarAndEvents(month) {
my.set('month', month);
// my.set(date,'today');
my.showMenuAndList('', 'date', 'today');
my.showCalendar('', 'month');
return false;
};
// update menu, list and calendar widget by entries of given month YYYY-MM
my.showCalendarAndEventsByMonth = function showCalendarAndEventsByMonth(
month) {
my.set('month', month);
my.showMenuAndList('', 'month');
my.showCalendar('', 'month');
return false;
};
// update menu, list and calendar widget by entries of given date YYYY-MM-DD
my.showCalendarAndEventsByDate = function showCalendarAndEventsByDate(date) {
my.set('date', date);
my.showMenuAndList('', 'date');
my.set('month', date);
my.showCalendar('', 'month');
return false;
};
// end of Calendar actions
// show comment for given event id and start time
my.showCommentsByEventIdOrEventStart = function showCommentsByEventIdOrEventStart(
event_id, event_start) {
var url = my.get('comments_url');
if (event_id == '' || event_start == '' || url == '')
return false;
my.set('comments_event_start', event_start);
my.set('comments_event_id', event_id);
url += event_id + '/' + event_start + '/';
my.updateContainer('calcms_comments', url);
}
// add a comment to a event
my.addComment = function addComment(id, comment) {
var url = my.get('add_comment_url');
if (url != '')
$.post(url, $("#" + id).serialize(), function(data) {
my.showCommentsByEventIdOrEventStart(my
.get('comments_event_id'), my
.get('comments_event_start'));
});
return false;
}
// insert new comment form
my.showCommentForm = function showCommentForm(id, parent_id, event_id,
event_start) {
var response = '<div>';
if (parent_id != '')
response += 'Deine Anwort:';
document.getElementById(id).innerHTML = response
+ '<form id="add_comment_'
+ parent_id
+ '" '
+ ' action="/agenda/kommentar_neu/?" method="post" '
+ ' onsubmit="calcms.addComment(\'add_comment_'
+ parent_id
+ '\',this);return false;" '
+ '>'
+ ' Name: *<br /> '
+ ' <input name="author" maxlength="40" /><br /> '
+ ' Was ich sagen will, ist: *<br /> '
+ ' <textarea name="content" cols="60" rows="10" '
+ ' onkeyup="javascript:if (this.value.length>1000) this.value=this.value.substr(0,1000)" '
+ ' ></textarea><br />'
+ ' Email: (f&uuml;r R&uuml;ckmeldungen, wird nicht angezeigt)<br /> '
+ ' <input name="email" maxlength="40" /><br /> '
+ ' <input type="submit" value="abschicken!" /> '
+ ' <input name="event_id" value="' + event_id
+ '" type="hidden" /> '
+ ' <input name="parent_id" value="' + parent_id
+ '" type="hidden" /> '
+ ' <input name="event_start" value="' + event_start
+ '" type="hidden" /> ' + '</form>' + '</div>';
// $("#"+id).show("drop");
my.show(id);
}
// end of Comment actions
// used to embed playlist in external pages
my.showPlaylist = function showPlaylist() {
var url = my.get('playlist_url');
my.updateContainer('calcms_playlist', url);
}
// load comments into #calcms_newest_comments if not embedded yet
my.showNewestComments = function showNewestComments() {
if (my.get('preloaded') == '') {
var url = my.get('newest_comments_url');
my.updateContainer('calcms_newest_comments', url);
}
return false;
}
// export selected events to ical
my.exportSelectedToICal = function exportSelectedToICal() {
window.location = my.get('ical_url') + my.setAndGetUrlParameters();
;
return false;
}
// init search interface: load search form content if not loaded yet
my.initSearch = function initSearch(target, field) {
if (my.get('preloaded') == '') {
var category_url = my.get('category_url');
var program_url = my.get('program_url');
var series_name_url = my.get('series_name_url');
var debug = my.get('debug');
if (category_url != null && category_url != '')
my.updateContainer('calcms_categories', category_url, 1);
if (program_url != null && program_url != '')
my.updateContainer('calcms_programs', program_url, 1);
if (series_name_url != null && series_name_url != '')
my.updateContainer('calcms_series_names', series_name_url, 1);
}
return false;
}
// wrapper to show an id
my.show = function show(id) {
$("#" + id).show("drop");
document.getElementById(id).style.visibility = "visible";
// document.getElementById(id).style.display="block";
}
// wrapper to hide an id
my.hide = function hide(id) {
$("#" + id).hide("drop");
document.getElementById(id).style.visibility = "hidden";
// document.getElementById(id).style.display="none";
}
// return max date
my.setDateIfBefore = function setDateIfBefore(date1, date2) {
if (date1 < date2)
return date2;
return date1;
}
// return min date
my.setDateIfAfter = function setDateIfAfter(date1, date2) {
if (date1 > date2)
return date2;
return date1;
}
// remove Drupal header for currently playing entry at topic overview page
my.removeCurrentPlayingHeader = function removeCurrentPlayingHeader() {
$("h2 a[href$='/testing']").each(function() {
$(this).css("display", "none");
});
}
// return instance
return my;
}(jQuery));

File diff suppressed because one or more lines are too long

6
website/agenda/js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,20 @@
<IfModule mod_perl.c>
<FilesMatch "\.cgi$">
SetHandler perl-script
PerlResponseHandler ModPerl::PerlRunPrefork
PerlOptions +ParseHeaders
Options +ExecCGI
#PerlSetVar PerlRunOnce On
#SetInputFilter apreq2
#APREQ2_ReadLimit 200M
</FilesMatch>
</IfModule>
<IfModule !mod_perl.c>
# AddHandler cgi-script .cgi .pl
</IfModule>
LimitRequestBody 2000000000
Require all granted

View File

@@ -0,0 +1,239 @@
#! /usr/bin/perl -w
use warnings "all";
use strict;
use Data::Dumper;
use params;
use config;
use log;
use template;
use auth;
use uac;
use roles;
use project;
use studios;
use events;
use series;
use series_schedule;
use series_events;
use series_dates;
use markup;
use URI::Escape;
use Encode;
use localization;
binmode STDOUT, ":utf8";
my $r=shift;
(my $cgi, my $params, my $error)=params::get($r);
my $config = config::get('../config/config.cgi');
my $debug = $config->{system}->{debug};
my ($user,$expires) = auth::get_user($cgi, $config);
return if ((!defined $user) || ($user eq ''));
#print STDERR $params->{project_id}."\n";
my $user_presets=uac::get_user_presets($config, {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
user => $user
});
$params->{default_studio_id}=$user_presets->{studio_id};
$params->{studio_id} = $params->{default_studio_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
$params->{project_id} = $user_presets->{project_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
#print STDERR $params->{project_id}."\n";
my $request={
url => $ENV{QUERY_STRING}||'',
params => {
original => $params,
checked => check_params($params),
},
};
$request = uac::prepare_request($request, $user_presets);
log::init($request);
$params=$request->{params}->{checked};
#process header
my $headerParams=uac::set_template_permissions($request->{permissions}, $params);
$headerParams->{loc} = localization::get($config, {user=>$user, file=>'menu'});
template::process('print', template::check('default.html'), $headerParams);
return unless uac::check($config, $params, $user_presets)==1;
print q{
<script src="js/datetime.js" type="text/javascript"></script>
<script src="js/event.js" type="text/javascript"></script>
<script src="js/localization.js" type="text/javascript"></script>
<link rel="stylesheet" href="css/series.css" type="text/css" />
};
my $permissions=$request->{permissions};
unless ($permissions->{scan_series_events}==1){
uac::permissions_denied('scan_series_events');
return;
}
if (defined $params->{action}){
assign_series ($config, $request) if ($params->{action} eq 'assign_series');
}
show_events($config, $request);
sub show_events{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
unless ($permissions->{assign_series_events}==1){
uac::permissions_denied('assign_series_events');
return;
}
my $projects=project::get($config, {project_id=>$params->{project_id}});
my $project=$projects->[0];
return unless (@$projects==1);
my $studios=studios::get($config, {project_id=>$params->{project_id}, studio_id=>$params->{studio_id}});
my $studio=$studios->[0];
return unless (@$studios==1);
my $project_name=$project->{name};
my $studio_name=$studio->{location};
#get series_names
my $dbh=db::connect($config);
my $query=q{
select project_id, studio_id, series_id, series_name, title
from calcms_series s, calcms_project_series ps
where s.id=ps.series_id
order by series_name, title
};
my $results=db::get($dbh, $query);
# get projects by id
my $projects_by_id={};
$projects=project::get($config);
for my $project (@$projects){
$projects_by_id->{$project->{project_id}}=$project;
}
# get studios by id
my $studios_by_id={};
$studios=studios::get($config);
for my $studio (@$studios){
$studios_by_id->{$studio->{id}}=$studio;
}
#add project and studio name to series
for my $result (@$results){
$result->{project_name} = $projects_by_id->{ $result->{project_id} }->{name};
$result->{studio_name} = $studios_by_id->{ $result->{studio_id} }->{location};
$result->{series_name} = 'Einzelsendung' if $result->{series_name} eq '_single_';
}
$params->{series}=$results;
#fill template
$params->{project_name} = $project_name;
$params->{studio_name} = $studio_name;
template::process('print', $params->{template}, $params);
}
sub assign_series{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
unless ($permissions->{assign_series_events}==1){
uac::permissions_denied('assign_series_events');
return;
}
my $entry={};
for my $attr ('project_id','studio_id', 'series_id'){
if (defined $params->{$attr}){
$entry->{$attr}=$params->{$attr};
}else{
uac::print_error($attr.' not given!');
return;
}
}
$config->{access}->{write}=1;
#check if series is assigned to project/studio
my $series=series::get(
$config,{
project_id => $entry->{project_id},
studio_id => $entry->{studio_id},
series_id => $entry->{series_id},
}
);
#print Dumper($series);
if(@$series==0){
# assign series to project/studio
project::assign_series(
$config,{
project_id => $entry->{project_id},
studio_id => $entry->{studio_id},
series_id => $entry->{series_id},
}
);
#print "assign\n";
}else{
print STDERR "event $entry->{event_id} already assigned to project $entry->{project_id}, studio $entry->{studio_id}, series $entry->{series_id}\n";
#print "is schon\n";
}
$config->{access}->{write}=0;
uac::print_info("event successfully assigned to series");
}
sub check_params{
my $params=shift;
my $checked={};
my $debug=$params->{debug} || '';
if ($debug=~/([a-z\_\,]+)/){
$debug=$1;
}
$checked->{debug}=$debug;
#actions and roles
$checked->{action}='';
if (defined $params->{action}){
if ($params->{action}=~/^(assign_series)$/){
$checked->{action}=$params->{action};
}
}
#numeric values
$checked->{exclude}=0;
for my $param ('id', 'project_id', 'studio_id', 'series_id'){
if ((defined $params->{$param})&&($params->{$param}=~/^\d+$/)){
$checked->{$param}=$params->{$param};
}
}
if (defined $checked->{studio_id}){
$checked->{default_studio_id}=$checked->{studio_id};
}else{
$checked->{studio_id}=-1;
}
$checked->{template}=template::check($params->{template},'assign_series');
return $checked;
}
__DATA__
SELECT ps.project_id, ps.studio_id, ps.series_id,p.name,s.name,se.series_name,se.title
FROM calcms_project_series ps ,calcms_projects p,calcms_studios s,calcms_series se
where ps.project_id=p.project_id and ps.studio_id=s.id and ps.series_id=se.id
order by se.series_name,p.name,s.name

View File

@@ -0,0 +1,397 @@
#! /usr/bin/perl -w
use warnings "all";
use strict;
use Data::Dumper;
use params;
use config;
use log;
use template;
use auth;
use uac;
use roles;
use project;
use studios;
use events;
use series;
use series_schedule;
use series_events;
use series_dates;
use markup;
use URI::Escape;
use Encode;
use localization;
binmode STDOUT, ":utf8";
my $r=shift;
(my $cgi, my $params, my $error)=params::get($r);
my $config = config::get('../config/config.cgi');
my $debug = $config->{system}->{debug};
my ($user,$expires) = auth::get_user($cgi, $config);
return if ((!defined $user) || ($user eq ''));
#print STDERR $params->{project_id}."\n";
my $user_presets=uac::get_user_presets($config, {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
user => $user
});
$params->{default_studio_id}=$user_presets->{studio_id};
$params->{studio_id} = $params->{default_studio_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
$params->{project_id} = $user_presets->{project_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
#print STDERR $params->{project_id}."\n";
my $request={
url => $ENV{QUERY_STRING}||'',
params => {
original => $params,
checked => check_params($params),
},
};
$request = uac::prepare_request($request, $user_presets);
log::init($request);
$params=$request->{params}->{checked};
#process header
my $headerParams=uac::set_template_permissions($request->{permissions}, $params);
$headerParams->{loc} = localization::get($config, {user=>$user, file=>'menu'});
template::process('print', template::check('default.html'), $headerParams);
return unless uac::check($config, $params, $user_presets)==1;
print q{
<script src="js/datetime.js" type="text/javascript"></script>
<script src="js/event.js" type="text/javascript"></script>
<script src="js/localization.js" type="text/javascript"></script>
<link rel="stylesheet" href="css/series.css" type="text/css" />
};
my $permissions=$request->{permissions};
unless ($permissions->{scan_series_events}==1){
uac::permissions_denied('scan_series_events');
return;
}
if (defined $params->{action}){
assign_events ($config, $request) if ($params->{action} eq 'assign_events');
}
show_events($config, $request);
sub show_events{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
unless ($permissions->{assign_series_events}==1){
uac::permissions_denied('assign_series_events');
return;
}
my $projects=project::get($config, {project_id=>$params->{project_id}});
my $project=$projects->[0];
#print STDERR Dumper($project);
return unless (@$projects==1);
my $studios=studios::get($config, {project_id=>$params->{project_id}, studio_id=>$params->{studio_id}});
my $studio=$studios->[0];
#print STDERR Dumper($studio);
return unless (@$studios==1);
my $project_name=$project->{name};
my $studio_name=$studio->{location};
#get series_names
my $dbh=db::connect($config);
my $query=q{
select project_id, studio_id, series_id, series_name, title
from calcms_series s, calcms_project_series ps
where s.id=ps.series_id
order by series_name, title
};
my $results=db::get($dbh, $query);
# get projects by id
my $projects_by_id={};
$projects=project::get($config);
for my $project (@$projects){
$projects_by_id->{$project->{project_id}}=$project;
}
# get studios by id
my $studios_by_id={};
$studios=studios::get($config);
for my $studio (@$studios){
$studios_by_id->{$studio->{id}}=$studio;
}
#add project and studio name to series
for my $result (@$results){
$result->{project_name} = $projects_by_id->{ $result->{project_id} }->{name};
$result->{studio_name} = $studios_by_id->{ $result->{studio_id} }->{location};
$result->{series_name} = 'Einzelsendung' if $result->{series_name} eq '_single_';
}
$params->{series}=$results;
# get events not assigned to series
my $conditions=[];
my $bind_values=[];
if($project_name ne''){
push @$conditions, 'e.project=?';
push @$bind_values, $project_name;
}
if($studio_name ne''){
push @$conditions, 'e.location=?';
push @$bind_values, $studio_name;
}
$conditions=' and '.join(' and ',@$conditions) if(@$conditions>0);
$query=qq{
select e.id, program, project, location, start, series_name, title, episode, rerun
from calcms_events e left join calcms_series_events se on se.event_id =e.id
where se.event_id is null
$conditions
order by series_name,title,start
limit 1000
};
print '<pre>'.Dumper($query).Dumper($bind_values).'</pre>';
$results=db::get($dbh, $query, $bind_values);
# detect title and episode
for my $result(@$results){
$result->{rerun}.='';
if($result->{title}=~/\#(\d+)([a-z])?\s*$/){
$result->{episode}=$1 unless defined $result->{episode};
$result->{rerun}=$2||'' unless ($result->{rerun}=~/\d/);
$result->{title}=~s/\#\d+[a-z]?\s*$//;
$result->{title}=~s/\s+$//;
}
my $a=time::datetime_to_array($result->{start});
#print STDERR "($a->[0],$a->[1],$a->[2])\n";
$result->{weekday}=time::weekday($a->[0],$a->[1],$a->[2]);
$result->{weekday}=$time::names->{de}->{weekdays_abbr}->[$result->{weekday}-1];
}
#fill template
$params->{unassigned_events}= $results;
$params->{sum_events} = @$results;
$params->{project_name} = $project_name;
$params->{studio_name} = $studio_name;
template::process('print', $params->{template}, $params);
}
sub assign_events{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
unless ($permissions->{assign_series_events}==1){
uac::permissions_denied('assign_series_events');
return;
}
my $entry={};
for my $attr ('project_id','studio_id', 'series_id','event_ids'){
if (defined $params->{$attr}){
$entry->{$attr}=$params->{$attr};
}else{
uac::print_error($attr.' not given!');
return;
}
}
$config->{access}->{write}=1;
for my $event_id (split(/[\,\s]+/,$params->{event_ids})){
next unless $event_id=~/^\d+/;
$entry->{event_id}=$event_id;
#get and parse event
my $request2={
params=>{
checked=>events::check_params($config,
{
event_id => $entry->{event_id},
template => 'no',
limit => 1,
archive => 'all',
no_exclude => '1'
}
)
},
config => $request->{config},
permissions => $request->{permissions}
};
$request2->{params}->{checked}->{published}='all';
my $events=events::get($config, $request2);
my $event=$events->[0];
unless (defined $event){
print STDERR "event not found for project $entry->{project_id}, studio $entry->{studio_id}, series $entry->{series_id}, event $entry->{event_id}\n";
next;
}
print STDERR "'".$event->{event_id}."' '".$event->{series_name}."' '".$event->{title}."' '".$event->{episode}."'\n";
#next;
#check if series is assigned to project/studio
my $series=series::get(
$config,{
project_id => $entry->{project_id},
studio_id => $entry->{studio_id},
series_id => $entry->{series_id},
}
);
if(@$series==0){
# assign series to project/studio
project::assign_series(
$config,{
project_id => $entry->{project_id},
studio_id => $entry->{studio_id},
series_id => $entry->{series_id},
}
);
}else{
print STDERR "event $entry->{event_id} already asigned to project $entry->{project_id}, studio $entry->{studio_id}, series $entry->{series_id}\n";
}
#get series
$series=series::get(
$config,{
project_id => $entry->{project_id},
studio_id => $entry->{studio_id},
series_id => $entry->{series_id},
}
);
if (@$series==1){
my $serie=$series->[0];
#set event's series name to value from series
my $series_name=$serie->{series_name}||'';
if ($series_name ne ''){
# prepend series_name from event to title on adding to single_events series
my $title=$event->{title};
if($serie->{has_single_events}eq'1'){
$title= $event->{series_name}.' - '.$title if $event->{series_name} ne '';
}
# save event content
series_events::save_content(
$config, {
studio_id => $entry->{studio_id},
id => $entry->{event_id}, #TODO: id=> event_id
series_name => $series_name,
title => $title,
episode => $event->{episode},
rerun => $event->{rerun},
modified_by => $params->{presets}->{user},
}
);
# add to history
$event->{project_id} = $entry->{project_id};
$event->{studio_id} = $entry->{studio_id};
$event->{series_id} = $entry->{series_id};
$event->{event_id} = $entry->{event_id};
$event->{series_name} = $series_name;
$event->{title} = $title;
$event->{user} = $params->{presets}->{user};
event_history::insert($config, $event);
# print STDERR "ok\n";
}
}else{
print STDERR "no series title found for studio $entry->{studio_id} series $entry->{series_id}, event $entry->{event_id}\n";
next;
}
#assign event
my $result=series::assign_event(
$config, {
project_id => $entry->{project_id},
studio_id => $entry->{studio_id},
series_id => $entry->{series_id},
event_id => $entry->{event_id},
manual => 1
}
);
unless(defined $result){
uac::print_error("error on assigning event to series");
return undef;
}
}
$config->{access}->{write}=0;
uac::print_info("event successfully assigned to series");
#$params->{getBack}=1;
}
sub check_params{
my $params=shift;
my $checked={};
my $debug=$params->{debug} || '';
if ($debug=~/([a-z\_\,]+)/){
$debug=$1;
}
$checked->{debug}=$debug;
#actions and roles
$checked->{action}='';
if (defined $params->{action}){
if ($params->{action}=~/^(assign_events)$/){
$checked->{action}=$params->{action};
}
}
#numeric values
$checked->{exclude}=0;
for my $param ('id', 'project_id', 'studio_id', 'series_id', 'event_id'){
if ((defined $params->{$param})&&($params->{$param}=~/^\d+$/)){
$checked->{$param}=$params->{$param};
}
}
for my $param ('event_ids'){
if ((defined $params->{$param})&&($params->{$param}=~/^[\d,]+$/)){
$checked->{$param}=$params->{$param};
}
}
if (defined $checked->{studio_id}){
$checked->{default_studio_id}=$checked->{studio_id};
}else{
$checked->{studio_id}=-1;
}
$checked->{template}=template::check($params->{template},'assignments');
if((defined $checked->{action})&&($checked->{action}eq'save_schedule')){
#set defaults
$checked->{create_events}=0;
$checked->{publish_events}=0;
}
for my $param ('frequency', 'duration', 'default_duration', 'create_events', 'publish_events', 'live', 'count_episodes'){
if ((defined $params->{$param})&&($params->{$param}=~/(\d+)/)){
$checked->{$param}=$1;
}
}
#scalars
for my $param ('search', 'from', 'till'){
if (defined $params->{$param}){
$checked->{$param}=$params->{$param};
$checked->{$param}=~s/^\s+//g;
$checked->{$param}=~s/\s+$//g;
}
}
return $checked;
}
__DATA__
SELECT ps.project_id, ps.studio_id, ps.series_id,p.name,s.name,se.series_name,se.title
FROM calcms_project_series ps ,calcms_projects p,calcms_studios s,calcms_series se
where ps.project_id=p.project_id and ps.studio_id=s.id and ps.series_id=se.id
order by se.series_name,p.name,s.name

View File

@@ -0,0 +1,549 @@
#!/usr/bin/perl
local $| = 0;
use warnings;
use strict;
use Data::Dumper;
#use CGI;
use CGI::Simple ();
use ModPerl::Util ();
#use Apache2::Request;
#use Apache2::Upload;
#use Apache2::Reload;
#use Apache2::RequestRec ();
#use Apache2::RequestIO ();
#use Apache2::RequestUtil ();
#use Apache2::ServerRec ();
#use Apache2::ServerUtil ();
#use Apache2::Connection ();
#use Apache2::Log ();
#use APR::Table ();
#use ModPerl::Registry ();
use Date::Calc;
use Time::Local;
use File::Temp;
#use File::Copy;
#use Digest::MD5::File;
use config;
use log;
use localization;
use auth;
use uac;
use studios;
use series;
use template;
use audio_recordings;
#$|=1;
binmode STDOUT, ":utf8";
#print "HTTP/1.1 200 OK\n";
my $useCgi=0;
our $config = config::get('../config/config.cgi');
our $debug = $config->{system}->{debug};
my $base_dir = $config->{locations}->{base_dir};
my $tempDir = '/var/tmp';
my $uploadLimit = 200_000_000;
my %params = ();
my $error = '';
my $cgi = undef;
my $fh = undef;
#### MOD_PERL2
# my $req = Apache2::Request->new(
# Apache2::RequestUtil->request,
# POST_MAX => $uploadLimit,
# DISABLE_UPLOADS => 0
# );
# my $upload = $req->upload('upload');
# my $filename = $upload->filename;
# my $fh = $upload->fh;
# my $file_size = $upload->size;
#### CGI
# $CGI::POST_MAX = $uploadLimit;
# $CGI::TMPDIRECTORY = $tempDir;
# $cgi = new CGI();
# my $handle = $cgi->upload('upload');
# $fh = $handle->handle if (defined $handle);
# $error = $cgi->cgi_error() || '';
# %params = $cgi->Vars();
#### simple CGI
$CGI::Simple::POST_MAX = $uploadLimit;
$CGI::Simple::DISABLE_UPLOADS = 0;
$cgi = $cgi = CGI::Simple->new;
my $filename = $cgi->param('upload');
$fh = $cgi->upload($filename);
$error = $cgi->cgi_error() || '';
%params = $cgi->Vars();
my $params=\%params;
binmode $fh if defined $fh;
#print "Content-type:text/html; charset=UTF-8;\n\n";
my ($user, $expires) = auth::get_user($cgi, $config);
exit if (!defined $user) || ($user eq '');
my $user_presets = uac::get_user_presets( $config, {
user => $user,
project_id => $params->{project_id},
studio_id => $params->{studio_id}
});
$params->{default_studio_id} = $user_presets->{studio_id};
$params->{studio_id} = $params->{default_studio_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
$params->{project_id} = $user_presets->{project_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
my $request={
url => $ENV{QUERY_STRING} || '',
params => {
original => $params,
checked => check_params($params),
},
};
#delete $params->{presets};
#print Dumper($request->{params}->{checked});
$request = uac::prepare_request($request, $user_presets);
log::init($request);
$params = $request->{params}->{checked};
my $headerParams=uac::set_template_permissions($request->{permissions}, $params);
$headerParams->{loc} = localization::get($config, {user=>$user, file=>'menu'});
template::process('print', template::check('default.html'), $headerParams);
exit unless defined uac::check($config, $params, $user_presets);
print q{
<script src="js/audio_recordings.js" type="text/javascript"></script>
<link rel="stylesheet" href="css/audio_recordings.css" type="text/css" />
}unless(params::isJson);
my $permissions = $request->{permissions};
$params->{action} = '' unless defined $params->{action};
$params->{error} = $error || '';
#print STDERR Dumper($params);
if ($params->{action} eq 'upload'){
uploadRecording($config, $request);
}elsif($params->{action} eq 'delete'){
deleteRecording($config, $request);
}
showAudioRecordings($config, $request);
print STDERR "$0 ERROR: ".$params->{error}."\n" if $params->{error} ne '';
$params->{loc} = localization::get($config, {user=>$params->{presets}->{user}, file=>'event,comment'});
template::process('print', $params->{template}, $params);
#print Dumper($params->{project_id});
#delete $params->{presets};
#print STDERR Dumper($params);
exit;
sub uploadRecording{
my $config = shift;
my $request = shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
unless ($permissions->{upload_audio_recordings}==1){
uac::permissions_denied('upload_audio_recordings');
return;
}
for my $attr ('project_id', 'studio_id', 'series_id', 'event_id'){
unless (defined $params->{$attr}){
uac::print_error("missing ".$attr." to upload productions");
return;
}
}
if (defined $fh){
print STDERR "upload\n";
#print STDERR Dumper($fh)."<br>";
my $fileInfo = uploadFile($config, $fh, $params->{event_id}, $user, $params->{upload});
$params->{error} .= $fileInfo->{error} if defined $fileInfo->{error};
$params->{path} = $fileInfo->{path};
$params->{size} = $fileInfo->{size};
$params->{duration} = $fileInfo->{duration};
$params = updateDatabase($config, $params, $user) if $params->{error} eq '';
}else{
$params->{error}.='Could not get file handle';
}
if ($params->{error} ne ''){
if ($params->{error}=~/limit/){
$params->{error} .= "audio file size is limited to ".int( $uploadLimit/1000000 )." MB!"
. "Please make it smaller and try again!";
}else{
$params->{error} .= "Error:'$error'";
}
}
}
# return 1 if file has been deleted
sub deleteFile{
my $file=shift;
return 0 unless defined $file;
if (-e $file){
if ( -w $file ){
unlink $file;
# check if file has been deleted
if ( -e $file ){
uac::print_error("could not delete audio file '$file', $!\n");
return 0;
}
}else{
uac::print_error("cannot delete audio file '$file', missing permissions\n");
return 0;
}
}
return 1;
}
sub deleteRecording{
my $config = shift;
my $request = shift;
my $params = $request->{params}->{checked};
my $permissions = $request->{permissions};
unless ($permissions->{delete_audio_recordings}==1){
uac::permissions_denied('delete_audio_recordings');
return;
}
for my $attr ('project_id', 'studio_id',
#'series_id',
'event_id', 'path'){
unless (defined $params->{$attr}){
uac::print_error("missing ".$attr." to delete production");
return;
}
}
my $dbh = db::connect($config);
$config->{access}->{write} = 0;
my $audioRecordings = audio_recordings::get($config, {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
event_id => $params->{event_id},
path => $params->{path}
});
unless ( (defined $audioRecordings) && (scalar @$audioRecordings >0)){
uac::print_error("could not find audio file $params->{path} in database");
return;
}
my $targetDir = $config->{locations}->{local_audio_recordings_dir};
unless ( defined $targetDir ){
uac::print_error("'local_audio_recordings_dir' is not configured.");
return;
}
unless ( -d $targetDir ){
uac::print_error("audio dir '$targetDir' does not exist");
return;
}
my $file = $targetDir.'/'.$params->{path};
print STDERR "ERROR: cannot delete audio file '$file', file does not exist\n" unless -e $file;
my $isDeleted = deleteFile($file);
return unless $isDeleted;
$config->{access}->{write}=1;
$audioRecordings = audio_recordings::delete($config, $dbh, {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
event_id => $params->{event_id},
path => $params->{path},
});
$config->{access}->{write}=0;
}
sub showAudioRecordings{
my $config = shift;
my $request = shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
for my $attr ('project_id', 'studio_id', 'series_id', 'event_id'){
unless (defined $params->{$attr}){
uac::print_error("missing ".$attr." to show productions");
return;
}
}
my $event=series::get_event($config, {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
event_id => $params->{event_id}
});
unless (defined $event){
uac::print_error("event not found");
}
#print '<pre>'.Dumper($event).'</pre>';
my $audioRecordings = audio_recordings::get($config, {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
event_id => $params->{event_id},
});
for my $recording (@$audioRecordings){
$recording->{size}=~s/(\d)(\d\d\d)$/$1\.$2/g;
$recording->{size}=~s/(\d)(\d\d\d\.\d\d\d)$/$1\.$2/g;
}
my $now = time();
my $timeZone=$config->{date}->{time_zone};
my $start = time::datetime_to_utc($event->{start}, $timeZone);
my $end = time::datetime_to_utc($event->{end}, $timeZone);
if ($now > $end){
uac::print_error("upload is expired due to the show is over");
$params->{isOver}=1;
}
my $days = 24 * 60 * 60;
uac::print_warn("show is more than a week ahead") if ( $now + 7 * $days ) < $start;
$params->{event} = $event;
$params->{audio_recordings} = $audioRecordings;
}
sub uploadFile{
my $config = $_[0];
my $fh = $_[1];
my $eventId = $_[2];
my $user = $_[3] || '';
my $filename = $_[4] || '';
# check target directory
my $targetDir = $config->{locations}->{local_audio_recordings_dir};
return { error => "could not find local_audio_recordings_dir" } unless defined $targetDir;
return { error => "local_audio_recordings_dir does not exist" } unless -e $targetDir;
# save file to disk
my $userName = $user;
$userName =~ s/[^a-zA-Z0-9\.\-\_]//g;
my $time = time::time_to_datetime();
$time =~ s/\:/\-/g;
$time =~ s/\s/\_/g;
$time =~ s/[^a-zA-Z0-9\.\-\_]//g;
$filename =~ s/[^a-zA-Z0-9\.\-\_]//g;
$filename =~ s/\.(mp3)$//g;
$filename = join('-', ($time, 'id'.$eventId, $userName, $filename)).'.mp3';
my $tempFile = $targetDir.'/'.$filename;
print STDERR "tempFile=$tempFile\n";
my $start = time();
open DAT, '>', $tempFile or return { error => 'could not save upload. '.$!." ".$tempFile };
binmode DAT;
my $size=0;
my $data='';
while( my $bytesRead = $fh->read( $data, 65000) ){
print DAT $data;
$size += $bytesRead;
$data='';
}
close DAT;
# get filename from content
#my $md5Filename = Digest::MD5::File::file_md5_hex($tempFile);
#$md5Filename = ~s/[\/\+]+/_/g;
#print STDERR "md5Filename=$md5Filename\n";
## rename file to name from content
#my $targetFilename = $eventId.'-'.$md5Filename.'-'.$userName.'-'.$time.'.mp3';
#my $targetFile = $targetDir.'/'.$targetFilename;
#print STDERR "targetFile=$targetFile\n";
#File::Copy::move( $tempFile, $targetFile);
#return { error => 'could not create $targetFile' } unless -e $targetFile;
return {
dir => $targetDir,
path => $filename,
size => $size,
};
}
sub updateDatabase{
my $config = shift;
my $params = shift;
my $user = shift;
my $entry={
project_id => $params->{project_id},
studio_id => $params->{studio_id},
event_id => $params->{event_id},
path => $params->{path},
md5 => $params->{md5}||'',
size => $params->{size},
created_by => $user
};
print STDERR "updateDatabase:".Dumper($entry);
#connect
$config->{access}->{write}=1;
my $dbh=db::connect($config);
my $entries = audio_recordings::get(
$config, {
project_id => $entry->{project_id},
studio_id => $entry->{studio_id},
event_id => $entry->{event_id},
path => $entry->{path}
}
);
if ( (defined $entries) && (scalar @$entries > 0) ){
print STDERR "update\n";
audio_recordings::update($config, $dbh, $entry);
my $entry = $entries->[0];
$params->{id} = $entry->{id};
}else{
print STDERR "insert\n";
$entry->{created_by} = $user;
$params->{id} = audio_recordings::insert($config, $dbh, $entry);
}
$config->{access}->{write} = 0;
$params->{action_result} = 'done!';
return $params;
}
# return filename, filehandle and optionally error from upload
sub getFilename{
my $cgi = shift;
my $upload = shift;
if (defined $upload){
# try apache2 module
my $filename = $upload->filename();
return {
filename => $filename,
fh => $upload->fh(),
error => ''
};
}
#print STDERR "cgi:".Dumper($cgi);
# fallback to CGI module
my $file = $cgi->param("upload");
return { error => "is no file" } if (defined $file) && ($file=~/\|/);
#print STDERR "file:".Dumper($file);
my $fileInfo = $cgi->uploadInfo($file);
#print STDERR "fileInfo:".Dumper($fileInfo);
if (defined $fileInfo){
my $filename=$fileInfo->{'Content-Disposition'}||'';
if ($filename=~/filename=\"(.*?)\"/){
$filename=$1;
return {
filename => $filename,
fh => $file,
error => ''
};
}
}
#error
return {
error => 'Could not detect file name!'
};
}
# get extension and optionally error
sub checkFilename{
my $filename = shift;
my @validExtensions=('mp3');
if($filename =~ /\.([a-zA-Z]{3,5})$/){
my $extension = lc $1;
unless(grep(/$extension/, @validExtensions)) {
return {
error => 'Following file formats are supported: '.join(",", @validExtensions).'!'
};
}
return{
extension => $extension,
error => ''
};
}
return {
error => 'Not matching file extension found! Supported are: '.join(",", @validExtensions).'!'
};
}
sub check_params{
my $params=shift;
my $checked={};
$checked->{error}='';
$checked->{template} = template::check($params->{template}, 'upload_audio_recordings');
#print Dumper($params);
#numeric values
for my $param ('project_id', 'studio_id', 'default_studio_id', 'series_id', 'event_id','id'){
if ((defined $params->{$param})&&($params->{$param}=~/^\d+$/)){
$checked->{$param} = $params->{$param};
}
}
if (defined $checked->{studio_id}){
$checked->{default_studio_id} = $checked->{studio_id};
}else{
$checked->{studio_id} = -1;
}
#word
for my $param ('debug', 'name', 'description'){
if ((defined $params->{$param}) && ($params->{$param}=~/^\s*(.+?)\s*$/)){
$checked->{$param} = $1;
}
}
# words
for my $attr('action','path'){
if ((defined $params->{$attr}) && ($params->{$attr}=~/(\S+)/)){
$checked->{$attr} = $params->{$attr};
}
}
$checked->{upload} = $params->{upload};
return $checked;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,324 @@
#! /usr/bin/perl -w
use warnings "all";
use strict;
use URI::Escape;
use Encode;
use Data::Dumper;
use MIME::Base64;
use Encode::Locale;
use params;
use config;
use log;
use template;
use db;
use auth;
use uac;
#use roles;
use time;
use markup;
use project;
use studios;
use comments;
#use events;
#use series;
#use series_dates;
#use series_events;
#use user_stats;
use localization;
binmode STDOUT, ":utf8";
my $r=shift;
(my $cgi, my $params, my $error)=params::get($r);
my $config = config::get('../config/config.cgi');
my $debug = $config->{system}->{debug};
my ($user,$expires) = auth::get_user($cgi, $config);
return if ((!defined $user) || ($user eq ''));
my $user_presets=uac::get_user_presets($config, {
user => $user,
project_id => $params->{project_id},
studio_id => $params->{studio_id}
});
$params->{default_studio_id}=$user_presets->{studio_id};
$params->{studio_id}=$params->{default_studio_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
$params->{project_id}=$user_presets->{project_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
my $request={
url => $ENV{QUERY_STRING}||'',
params => {
original => $params,
checked => check_params($params),
},
};
#set user at params->presets->user
$request = uac::prepare_request($request, $user_presets);
log::init($request);
$params=$request->{params}->{checked};
#print Dumper($params);
#show header
if ((params::isJson()) || (defined $params->{action})){
print "Content-Type:text/html; charset=utf-8;\n\n";
}else{
my $headerParams=uac::set_template_permissions($request->{permissions}, $params);
$headerParams->{loc} = localization::get($config, {user=>$user, file=>'menu'});
template::process('print', template::check('default.html'), $headerParams);
print q{
<script src="js/datetime.js" type="text/javascript"></script>
}unless(params::isJson);
}
return unless defined uac::check($config, $params, $user_presets);
if (defined $params->{action}){
if ($params->{action} eq 'get_json') {
getJson($config, $request);
return;
}
if ($params->{action} eq 'setLock'){
setLock($config, $request);
return;
}
if ($params->{action} eq 'setRead'){
setRead($config, $request);
return;
}
}
$config->{access}->{write}=0;
showComments($config, $request);
sub showComments{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
unless ($permissions->{read_comment}==1){
uac::permissions_denied('read_comment');
return;
}
for my $attr ('project_id','studio_id'){
unless (defined $params->{$attr}){
uac::print_error("missing ".$attr." to show comment");
return;
}
}
$config->{access}->{write}=0;
my $dbh=db::connect($config);
my $comment =$params->{comment};
my $template_parameters={};
#my $nodes={};
#my $sorted_nodes=[];
my $results=[];
if ($params->{search} ne ''){
$params->{comment}->{search}=$params->{search};
$results=comments::get_by_event($dbh, $config, $request);
}elsif ($comment->{event_id} ne ''){
$results=comments::get_by_event($dbh, $config, $request);
}else{
$results=comments::get_by_time($dbh, $config, $comment);
}
my $events=[];
my $comment_count=0;
if (@$results>0){
my $comments=modify_comments($request, $results);
$comments=comments::sort($config, $comments);
$events=comments::get_events($dbh, $config, $request, $comments);
my $language= $config::config->{date}->{language} || 'en';
for my $event(@$events){
$event->{start}=time::date_time_format($event->{start}, $language);
$comment_count+=$event->{comment_count} if (defined $event->{comment_count});
$event->{cache_base_url} =$config::config->{cache}->{base_url};
}
}
for my $param (%$comment){
$template_parameters->{$param} = $comment->{$param};
}
$template_parameters->{search} = markup::fix_utf8($request->{params}->{original}->{search});
$template_parameters->{events} = $events;
$template_parameters->{debug} = $config->{system}->{debug};
$template_parameters->{event_count} = @$events+0;
$template_parameters->{comment_count} = $comment_count;
$template_parameters->{is_empty} = 1 if (@$events==0);
$template_parameters->{projects} = project::get_with_dates($config);
$template_parameters->{controllers} = $config->{controllers};
$template_parameters->{allow} = $permissions;
$template_parameters->{loc} = localization::get($config, {user=>$params->{presets}->{user}, file=>'comment'});
#fill and output template
template::process('print', $params->{template}, $template_parameters);
}
sub modify_comments{
my $request=shift;
my $results=shift;
my $language = $config::config->{date}->{language} || 'en';
for my $result (@$results){
$result->{start_date_name} = time::date_format($result->{created_at}, $language);
$result->{start_time_name} = time::time_format($result->{created_at});
$result->{$result->{lock_status}} = 1;
$result->{$result->{news_status}} = 1;
}
return $results;
}
sub setLock{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
unless ($permissions->{update_comment_status_lock}==1){
uac::permissions_denied('update_comment_status_lock');
return;
}
my $comment =$params->{comment};
$comment->{id} = $comment->{comment_id};
if ($comment->{id} eq ''){
return
}
#todo change set_news_status to lock_status in comment module
$comment->{set_lock_status}=$comment->{lockStatus};
$comment->{set_lock_status}='blocked' unless $comment->{set_lock_status} eq 'show';
$config->{access}->{write}=1;
my $dbh=db::connect($config);
print STDERR "setLock ".Dumper($comment);
comments::set_lock_status($dbh, $config, $comment);
print "done\n";
}
sub setRead{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
unless ($permissions->{update_comment_status_read}==1){
uac::permissions_denied('update_comment_status_read');
return;
}
$config->{access}->{write}=1;
my $dbh=db::connect($config);
my $comment =$params->{comment};
$comment->{id} = $comment->{comment_id};
if ($comment->{id} eq ''){
return;
}
#todo change set_news_status to read_status in comment module
$comment->{set_news_status}=$comment->{readStatus};
$comment->{set_news_status}='received' unless $comment->{set_news_status} eq 'unread';
print STDERR "setRead ".Dumper($comment);
comments::set_news_status($dbh, $config, $comment);
print "done\n";
}
sub check_params{
my $params=shift;
my $checked={};
#actions
if (defined $params->{action}){
if ($params->{action}=~/^(setLock|setRead|showComment)$/){
$checked->{action}=$params->{action};
}
}
#template
my $template='';
if (defined $checked->{action}) {
$template=template::check($params->{template},'edit_comment') if $checked->{action}eq'showComment';
}else{
$template=template::check($params->{template},'comments');
}
$checked->{template}=$template;
#numeric values
for my $param ('project_id', 'studio_id', 'default_studio_id'){
if ((defined $params->{$param})&&($params->{$param}=~/^\d+$/)){
$checked->{$param}=$params->{$param};
}
}
if (defined $checked->{studio_id}){
$checked->{default_studio_id}=$checked->{studio_id};
}else{
$checked->{studio_id}=-1;
}
my $comment={};
for my $key ('readStatus'){
my $value=$params->{$key};
$comment->{$key} = $value if (defined $value) && ($value=~/^(received|unread)$/);
}
for my $key ('lockStatus'){
my $value=$params->{$key};
$comment->{$key} = $value if (defined $value) && ($value=~/^(blocked|show)$/);
}
$comment->{event_start}=time::check_date($params->{event_start})||'';
$comment->{from}=time::check_date($params->{from})||'';
$comment->{till}=time::check_date($params->{till})||'';
my $event_id=$params->{event_id}||'';
if ($event_id=~/^(\d+)$/){
$comment->{event_id}=$1;
}else{
# error('invalid event_id');
}
$comment->{event_id}='' unless defined $comment->{event_id};
my $id=$params->{comment_id}||'';
if ($id=~/^(\d+)$/){
$comment->{comment_id}=$1;
}
$comment->{comment_id}='' unless defined $comment->{comment_id};
my $age=$params->{age}||'';
if ($age=~/^(\d+)$/){
$comment->{age}=$1;
}
$comment->{age}='365' unless defined $comment->{age};
my $search=$params->{search} || '';
if ((defined $search) && ($search ne '')){
$search=substr($search,0,100);
$search=~s/^\s+//gi;
$search=~s/\s+$//gi;
$search=~s/\-\-//gi;
$search=~s/\;//gi;
$checked->{search}=$search if $search ne '';
};
$checked->{search}='' unless defined $checked->{search};
$checked->{comment}=$comment;
return $checked;
}

View File

@@ -0,0 +1,298 @@
#! /usr/bin/perl -w
use warnings "all";
use strict;
use Data::Dumper;
use params;
use config;
#use log;
#use template;
use auth;
use uac;
#use roles;
#use project;
#use studios;
#use events;
use series;
#use series_schedule;
#use series_events;
#use series_dates;
#use markup;
#use URI::Escape;
#use Encode;
use localization;
binmode STDOUT, ":utf8";
my $r=shift;
(my $cgi, my $params, my $error)=params::get($r);
my $config = config::get('../config/config.cgi');
my $debug = $config->{system}->{debug};
my ($user,$expires) = auth::get_user($cgi, $config);
return if ((!defined $user) || ($user eq ''));
#print STDERR $params->{project_id}."\n";
my $user_presets=uac::get_user_presets($config, {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
user => $user
});
$params->{default_studio_id}=$user_presets->{studio_id};
$params->{studio_id} = $params->{default_studio_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
$params->{project_id} = $user_presets->{project_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
#print STDERR $params->{project_id}."\n";
my $request={
url => $ENV{QUERY_STRING}||'',
params => {
original => $params,
checked => check_params($params),
},
};
$request = uac::prepare_request($request, $user_presets);
log::init($request);
$params=$request->{params}->{checked};
#process header
my $headerParams=uac::set_template_permissions($request->{permissions}, $params);
$headerParams->{loc} = localization::get($config, {user=>$user, file=>'menu'});
template::process('print', template::check('default.html'), $headerParams);
return unless uac::check($config, $params, $user_presets)==1;
print q{
<script src="js/datetime.js" type="text/javascript"></script>
<script src="js/event.js" type="text/javascript"></script>
<script src="js/localization.js" type="text/javascript"></script>
<link rel="stylesheet" href="css/series.css" type="text/css" />
};
my $permissions=$request->{permissions};
unless ($permissions->{create_event_from_schedule}==1){
uac::permissions_denied('create_event_from_schedule');
return;
}
if (defined $params->{action}){
# assign_series ($config, $request) if ($params->{action} eq 'assign_series');
}
#print Dumper($params);
show_events($config, $request);
sub show_events{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
unless ($permissions->{assign_series_events}==1){
uac::permissions_denied('assign_series_events');
return;
}
#print STDERR Dumper($params);
#print '<pre>'.Dumper($eventsByStart);
#return;
my $scheduleDates=getScheduleDates($config, $request);
my $schedulesByStart=getEventsByDate($scheduleDates);
my $events=getEvents($config, $request);
my $eventsByStart=getEventsByDate($events);
print "<pre>\n";
for my $date (sort keys %$schedulesByStart){
my $schedules=$schedulesByStart->{$date};
my $scheduleCount=scalar(@$schedules);
if ($scheduleCount==0){
print "skip datetime $date, no schedule found\n";
next;
}
if ($scheduleCount>1){
print "skip datetime $date, $scheduleCount schedules found\n";
next;
}
my $schedule=$schedules->[0];
if (defined $eventsByStart->{$date}){
my $events=$eventsByStart->{$date};
my $eventCount=scalar(@$events);
if ($eventCount>0){
print "skip datetime $date, $eventCount events already exist\n";
next;
}
}
print "found schedule without event for $date"
." - "
. $schedule->{series_name}." - ".$schedule->{title}
. "\n";
#createEvent($config, $request, $schedule);
}
}
# get a list of events with given start datetime
sub getEventsByDate{
my $events=shift;
my $eventsByDate={};
for my $event (@$events){
my $startDate=$event->{start};
push @{$eventsByDate->{$startDate}}, $event;
}
return $eventsByDate;
}
sub getScheduleDates{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
my $options = {};
my $from=$params->{from_date};
my $till=$params->{till_date};
my $project_id = $params->{project_id};
my $studio_id = $params->{studio_id};
#build series filter
$options={
project_id => $project_id,
studio_id => $studio_id,
from => $from,
till => $till,
date_range_include => 1,
exclude => 0
};
#get all series dates
my $series_dates=series_dates::get_series($config, $options);
return $series_dates;
}
sub getEvents{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
my $options = {};
my $from=$params->{from_date};
my $till=$params->{till_date};
my $project_id = $params->{project_id};
my $studio_id = $params->{studio_id};
#build event filter
$options={
project_id => $project_id,
template => 'no',
limit => 600,
get => 'no_content',
from_date => $from,
till_date => $till,
date_range_include => 1,
archive => 'all',
no_exclude => '1',
};
my $events=getSeriesEvents($config, $request, $options, $params);
return $events;
}
sub getSeriesEvents{
my $config = shift;
my $request = shift;
my $options = shift;
my $params = shift;
#get events by series id
my $series_id=$request->{params}->{checked}->{series_id};
if (defined $series_id){
my $events=series::get_events($request->{config}, $options);
return $events;
}
#get events (directly from database to get the ones, not assigned, yet)
delete $options->{studio_id};
delete $options->{project_id};
my $request2={
params=>{
checked => events::check_params($config, $options)
},
config => $request->{config},
permissions => $request->{permissions}
};
$request2->{params}->{checked}->{published}='all';
delete $request2->{params}->{checked}->{exclude_locations} if (($params->{studio_id}==-1)&&(defined $request2->{params}->{checked}->{exclude_locations}));
my $events=events::get($config, $request2);
#print STDERR Dumper($request2->{params}->{checked});
#print STDERR Dumper($events);
series::add_series_ids_to_events($request->{config}, $events);
my $studios=studios::get($request->{config},{
project_id => $options->{project_id}
});
my $studio_id_by_location={};
for my $studio (@$studios){
$studio_id_by_location->{$studio->{location}}=$studio->{id};
}
for my $event (@$events){
$event->{project_id}= $options->{project_id} unless defined $event->{project_id};
$event->{studio_id} = $studio_id_by_location->{$event->{location}} unless defined $event->{studio_id};
}
return $events;
}
sub check_params{
my $params=shift;
my $checked={};
my $debug=$params->{debug} || '';
if ($debug=~/([a-z\_\,]+)/){
$debug=$1;
}
$checked->{debug}=$debug;
#actions and roles
$checked->{action}='';
if (defined $params->{action}){
if ($params->{action}=~/^(create_events)$/){
$checked->{action}=$params->{action};
}
}
#numeric values
$checked->{exclude}=0;
for my $param ('id', 'project_id', 'studio_id', 'series_id'){
if ((defined $params->{$param})&&($params->{$param}=~/^\d+$/)){
$checked->{$param}=$params->{$param};
}
}
if (defined $checked->{studio_id}){
$checked->{default_studio_id}=$checked->{studio_id};
}else{
$checked->{studio_id}=-1;
}
for my $param ('date','from_date','till_date'){
$checked->{$param}=time::check_date($params->{$param});
}
$checked->{template}=template::check($params->{template},'create_events');
return $checked;
}
__DATA__
https://piradio.de/agenda/planung/create_events.cgi?project_id=1&studio_id=1&from_date=2016-09-01&till_date=2016-10-01

View File

@@ -0,0 +1,416 @@
body{
margin:0;
padding:0;
color:#000;
background:#efefef;
height:100%;
text-align:center;
}
body #content{
margin:0;
padding:1em;
max-width:980px;
color:#000;
background:#fff;
line-height:100%;
text-align:left;
}
body,
#content input,
#content textarea,
#content td,
#content div,
#content select,
#content option,
#content li{
font-size:14px;
font-size:0.75rem;
font-family:sans-serif;
}
#content input,
#content textarea{
border:1px solid #ccc;
padding:6px;
}
@media handheld{
body{
max-width:800px;
font-size:1em;
}
input,button{
padding:16px;
}
#calcms_admin_menu{
min-width:640px;
max-width:800px;
}
}
#calcms_admin_menu{
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
vertical-align:middle;
z-index:99;
}
#calcms_admin_menu,
#calcms_admin_menu a,
#calcms_admin_menu div,
#calcms_admin_menu input,
#calcms_admin_menu select,
#calcms_admin_menu option,
#calcms_admin_menu img
{
margin:0;
padding:0;
color:#fff;
}
#calcms_admin_menu img{
border:0;
vertical-align:middle;
}
#calcms_admin_menu,
#calcms_admin_menu select{
background:#444;
}
#calcms_admin_menu div a,
#calcms_admin_menu select{
font-size:14px;
padding:6px;
padding-top:1em;
padding-bottom:1em;
line-height:3em;
}
#calcms_admin_menu div:hover,
#calcms_admin_menu select:hover{
background:#888;
}
#calcms_admin_menu select,
#calcms_admin_menu option{
font-size:0.8rem;
width:8em;
border:0;
padding-left:0;
padding-right:0;
border-left:1px solid #666;
}
#calcms_admin_menu a#logout{
color:#ff4444;
}
a{
color:#000;
text-decoration:none;
}
#content table{
margin:1;
border-collapse:collapse;
width:100%
}
#content table td{
padding:6px;
border-collapse:collapse;
border-right:0;
border-left:0;
}
#content table th{
padding:6px;
border-collapse:collapse;
}
#info{
color:#000;
background:#fff;
}
#content textarea{
font-weight:normal;
}
#content div{
padding:6px;
}
#content div.header{
font-size:16px;
text-align:left;
padding-left:0;
}
#content .field{
width:30em;
}
#content .button{
width:10em;
}
*:focus {outline: none;}
#content a{
color:#000;
font-weight:normal;
}
#content a:hover{
text-decoration:underline;
}
#content form{
border:0;
padding:0;
margin:0;
}
#content div,td,tr,table{
vertical-align:middle;
}
#content td{
padding:3px;
}
#content pre, .pre {
border:0;
padding:2em;
color:#000;
background:#eee;
}
.error.head{
position:relative;
top:3em;
}
li.ui-menu-item{
background:none;
list-style-image:url();
list-style-type:none;
}
#content h1,
#content h2{
margin:1em;
padding:0;
font-weight:100;
}
#jobs th{
text-align:left;
}
#jobs td.status.finished a{
color:#000;
}
#jobs td.status.ongoing a{
text-decoration:blink;
color:green;
}
#jobs td.status.scheduled a{
color:green;
}
div.ok{
border:2px solid #aca;
background:#cfc;
background: linear-gradient(to right, #cfc, white);
opacity:0.8;
}
div.warn{
border:2px solid #ff0;
background:#ff0;
background: linear-gradient(to right, #ff3, white);
opacity:0.8;
}
div.error{
border:2px solid #f99;
background:#fcc;
background: linear-gradient(to right, #fcc, white);
opacity:0.8;
}
#content button,
#content select,
#content input{
padding:4px;
}
#content div.flex{
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
#content div.card{
border:0;
margin:1em;
box-shadow:0 2px 5px 0 rgba(0,0,0,.12),0 2px 10px 0 rgba(0,0,0,.09);
border-radius:3px;
}
#content div.card div.title{
font-size:16px;
}
#content table.table tr{
border-bottom:solid 1px #ebebeb;
}
#content table.table tr:hover{
background:#ebebeb
}
#content div.card tr{
border-bottom:none;
}
#content div.card tr:hover{
background:none;
}
/*overwrite jquery ui*/
#content .ui-tabs-nav{
border:0;
background:#fff;
border-bottom: solid 1px #ccc;
}
#content .ui-tab a{
color:#fff;
}
#content .ui-tabs-tab{
border:0;
background:#aaa;
padding:6px;
border-radius: 3px 3px 0 0;
}
#content .ui-tab a:hover{
text-decoration:none;
}
/* overwrite tablesorter */
tr.tablesorter-filter-row{
background:#ccc;
}
tr.tablesorter-filter-row input{
height:1rem;
color:#000;
}
/*colors*/
#content button,
#content .ui-state-active,
#content a.ui-button:active,
#content .ui-button:active{
background-color:#2196f3;
}
#content button:hover,
#content .ui-button.ui-state-active:hover{
background-color:#39a1f4;
}
/*colors end */
#content button{
border:none;
color:#fff;
padding:8px;
margin-top:0px;
margin-bottom:0px;
margin-left:6px;
text-align: center;
text-decoration: none;
font-size: 12px;
}
#content button{
box-shadow:0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);
position:relative;
transition:background-color .3s cubic-bezier(.64,.09,.08,1),box-shadow .3s cubic-bezier(.64,.09,.08,1);
padding:10px 20px;
display:inline-block;
border:0
}
#content button:focus{
outline:0;
transition:all 0.5s cubic-bezier(.64,.09,.08,1)
}
#content button:hover{
box-shadow:0 5px 11px 0 rgba(0,0,0,.18),0 4px 15px 0 rgba(0,0,0,.15);
}
#content input{
border:none;
border-bottom:1px solid #03a9f4;
color:#000;
background:#fefefe;
padding:8px;
margin-top:0px;
margin-bottom:0px;
margin-left:6px;
text-decoration: none;
}
#content input:focus{
border-bottom:2px solid #03a9f4;
}
#content textarea:focus{
border:1px solid #03a9f4;
}
#content select{
color:#000;
padding:6px;
padding-left:0;
padding-right:0;
border:none;
border-bottom:solid 1px #9e9e9e;
cursor:pointer;
margin-left:6px;
}
#content select,
input[type='checkbox']{
margin-top:0px;
}
#content div.buttons button{
margin-bottom:6px;
}
#content div.formField div.label{
display:hide;
padding-left:1em;
color:#999;
}
#content div.formField input{
clear:both;
}

View File

@@ -0,0 +1,13 @@
img{
margin-right :1em;
vertical-align:middle
}
#content div.panel{
padding:1em;
}
h2 {
line-height:1.5em;
}

View File

@@ -0,0 +1,532 @@
body #content{
padding:0;
}
button:hover{
cursor:pointer;
}
@media print{
#calcms_admin_menu{
display:none;
}
#toolbar{
display:none;
}
tr,td,div.event,div.schedule,div.work,div.play{
border:1pt solid black;
}
#content{
top:0;
}
}
#content #calendar_weekdays,
#content #calendar_weekdays table,
#content #calendar{
position:absolute;
padding:0;
left:0;
}
#content #calendar_weekdays{
font-size:12px;
}
@media screen{
#content #calendar{
overflow-x:hidden;
overflow-y:scroll;
}
}
#calendar_weekdays table,
#calendar table{
table-layout:fixed;
}
#calendar_weekdays table td,
#calendar table td{
vertical-align:top;
padding:0;
min-width:100px;
}
#calendar_weekdays table td{
white-space:normal;
}
#calendar_weekdays table td:nth-child(1),
#calendar table td:nth-child(1){
min-width:80px !important;
}
#calendar table td{
word-wrap:break-word;
hyphens:auto;
/*word-break:break-all;*/
}
#calendar div.text{
padding-right:0;
}
@media (min-width: 720em) {
#calendar div.text{
padding-right:16px;
}
}
#calendar div.event img{
width:16px;
height:16px;
border:0;
margin:-2px;
padding:0px;
}
#event_list tr{
border-bottom:1px solid #999;
}
#calendar div.schedule div.text,
#calendar div.event div.text{
positions:absolute;
top:0;
left:0;
padding-left:0;
padding-top:0;
padding-bottom:0;
/*
// padding-right:16px;
*/
}
#calendar div.event div.icons{
position:absolute;
top:-5px;
right:-7px;
width:16px;
image-rendering: optimizeSpeed; /* FUCK SMOOTHING, GIVE ME SPEED */
image-rendering: -moz-crisp-edges; /* Firefox */
image-rendering: -o-crisp-edges; /* Opera */
image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */
image-rendering: optimize-contrast; /* CSS3 Proposed */
-ms-interpolation-mode: nearest-neighbor; /* IE8+ */
}
/*
#calendar div.event,
#calendar div.schedule{
border-bottom:1px solid black;
}
*/
#calendar div.time.now {
padding:0;
margin:0;
border:2px dashed #99f;
width:100%;
height:0px;
z-index:0;
}
#calendar_weekdays div.date,
#calendar div.time {
text-align:center;
vertical-align:middle;
z-index:5;
}
#calendar_weekdays div.date.today {
background:#ccf;
}
#calendar div.grid{
overflow:hidden;
position:absolute;
background:white;
}
#calendar_weekdays td.week,
#calendar td.week{
padding:0;
width:0px;
min-width:0px;
max-width:0px;
}
#calendar_weekdays td.week div,
#calendar td.week div{
padding:0;
min-width:1px;
height:100%;
background:#666;
background-image:url(../image/chess.gif);
}
#calendar td.week div{
height:180em;
}
#calendar div.time,
#calendar_weekdays div.date,
#calendar div.event,
#calendar div.schedule,
#calendar div.work,
#calendar div.play{
overflow:hidden;
font-size:12px;
border-right:0;
position:absolute;
margin-left:0px;
border:0;
border-bottom:1px solid #666;
border-top:1px solid #666;
/*border:1px solid black;*/
}
#calendar div.time,
#calendar_weekdays div.date{
border:0;
}
#calendar div.time,
#calendar_weekdays div.time{
border-top:1px solid #666;
}
/* calendar list*/
#content div.event{
z-index:5;
}
#content div.schedule{
font-weight:normal;
z-index:4;
}
#content .scheduled{
color:#000;
font-weight:normal;
z-index:4;
}
#content div.work{
font-weight:normal;
z-index:3;
}
#content div.play{
font-weight:normal;
z-index:1;
}
#content div.grid{
z-index:1;
margin-left:0px;
background:white;
/*
// margin-right:15px;
*/
}
#event_list tr{
/*border-bottom:1px solid #999;*/
}
#event_list tr th:hover{
cursor:pointer;
}
#event_list tr th,
#event_list tr td,
#event_list .tablesorter-header-inner{
padding:6px;
padding-left:6px;
padding-right:0px;
}
input.tablesorter-filter{
width:4em;
}
#event_list tr td.day_of_year{
white-space: nowrap;
}
#event_list td:nth-child(1),
#event_list th:nth-child(1),
#event_list td:nth-child(1) .tablesorter-filter{
white-space: nowrap;
padding:0;
width:3em;
text-align:center;
}
#event_list tr td.weekday{
white-space: nowrap;
}
#event_list td:nth-child(2),
#event_list th:nth-child(2),
#event_list td:nth-child(2) .tablesorter-filter{
white-space: nowrap;
padding:0;
width:2em;
text-align:right;
}
#event_list tr td.start_date{
white-space: nowrap;
font-family:monospace;
}
#event_list tr .start_date{
text-align:left;
}
#event_list tr td.start_time{
white-space: nowrap;
}
#event_list tr td.series_name{
}
#event_list tr td.title{
max-width:20em;
}
#event_list tr td.user_title{
}
#event_list tr td.episode{
white-space: nowrap;
}
#event_list td:nth-child(7),
#event_list th:nth-child(7),
#event_list td:nth-child(7) .tablesorter-filter{
white-space: nowrap;
padding:0;
width:2em;
text-align:right;
}
#event_list tr td.rerun{
white-space: nowrap;
}
#event_list tr .rerun{
width:1em;
text-align:center;
}
#event_list td:nth-child(9),
#event_list th:nth-child(9),
#event_list td:nth-child(9) .tablesorter-filter{
white-space: nowrap;
padding:0;
width:1em;
text-align:center;
}
#event_list td:nth-child(10),
#event_list th:nth-child(10),
#event_list td:nth-child(10) .tablesorter-filter{
padding:0;
width:1em;
text-align:center;
}
#event_list tr:hover{
border-left:1px solid #333;
border-right:1px solid #333;
cursor:pointer;
}
/* calendar colors */
/*
#content .grid{
border:1px dashed #ccc;
}
*/
#content div.event.no_series{
color:#000;
}
#content.conflicts .schedule.error{
color:#000;
}
#content.conflicts .error{
color:#000;
}
/* color end*/
#content .weak{
font-weight:300;
}
#content .schedule,
#content .event{
cursor:pointer;
}
#content #calendar_weekdays td:nth-child(1) div.date a{
font-size:1.7em;
}
#content #position{
word-wrap:break-word;
word-break:normal;
text-align:center;
}
div#toolbar{
z-index:999;
padding:0;
width:100%;
background:#ddd;
display: flex;
flex-wrap: wrap;
align-items: center;
vertical-align:middle;
z-index:99;
}
div#toolbar div{
display:table-cell;
vertical-align:middle;
}
div#toolbar select{
padding:8px;
margin-left:6px;
}
div#toolbar input.search{
padding:9px;
}
#content #toolbar div{
padding:0;
padding-left:6px;
}
#content #toolbar div:hover,
#content #toolbar select:hover,
#content #toolbar input:hover{
background:#ccc;
padding-top:6px;
padding-bottom:6px;
}
#content #toolbar div#current_date{
cursor:pointer;
font-size:1.5em;
width:5em;
text-align:center;
padding:5px;
}
#content #toolbar div#previous_month,
#content #toolbar div#next_month{
cursor:pointer;
font-size:1.7em;
padding:6px;
}
#content #toolbar input#start_date{
display:none;
}
#series td{
padding:6px;
}
#calendar td div.play {
transition: min-height 0.1s;
transition: min-width 0.1s;
transition-delay: 0.7s;
}
#calendar td div.play:hover {
min-height: 180px!important;
min-width: 420px!important;
z-index:99;
box-shadow:0 2px 5px 0 rgba(0,0,0,.12),0 2px 10px 0 rgba(0,0,0,.09);
border-radius:3px;
}
#calendar td div.play:hover img{
display:show;
}
#calendar td div.play img{
position:absolute;
top:1em;
right:1em;
width:40%;
height:40%;
display:none;
}
#calendar td div.play img:hover{
cursor:pointer;
}
#calendar div.ui-draggable-dragging{
z-index:99;
cursor:move;
}
#calendar div.intersect{
background:#fcc;
}
#calendar div.event.error,
#calendar div.event.schedule{
width:50%;
}
#calendar div.event.error.x2,
#calendar div.event.schedule.x2{
margin-left:50%;
}
div.rms_detail{
width:100%
}
div.rms_detail div.image{
width:100%;
float:right;
}
div.rms_detail div.image img{
}
div.rms_detail div.text{
width:100%;
text-align:left;
float:left;
font-size:0.8rem;
}
div.event .ok,
div.play .ok{
background:#4caf50;
}
div.event .warn,
div.play .warn{
background:#ffeb3b;
}
div.event .error,
div.play .error{
background:#f44336;
}

View File

@@ -0,0 +1,128 @@
#comments td,th,input {
line-height:100%;
ffont-size:10px;
}
#comments td,th{
display:table-cell;
font-weight:normal;
padding:6px;
}
#comments td.level0, td.level1, td.level2, td.level3, td.level4, td.level5{
border:0;
}
#comments td.host{
color:gray;
}
#comments td.level0{
padding-left:0px;
}
#comments td.level1{
padding-left:20px;
}
#comments td.level2{
padding-left:40px;
}
#comments td.level3{
padding-left:60px;
}
#comments td.level4{
padding-left:80px;
}
#comments td.level5{
padding-left:100px;
}
#comments img.level0{
margin-left:0px;
}
#comments img.level1{
margin-left:20px;
}
#comments img.level2{
margin-left:40px;
}
#comments img.level3{
margin-left:60px;
}
#comments img.level4{
margin-left:80px;
}
#comments img.level5{
margin-left:100px;
}
#comments tr{
vertical-align:middle;
}
#comments tr.show{
color:#030;
text-decoration:none;
}
#content tr.show td{
padding-top:0px;
padding-bottom:0px;
}
#comments tr.blocked{
color:#a33;
text-decoration:break-through;
}
#comments textarea{
width:100%;
}
#comments td.content.unread{
font-weight:bold;
}
#comments td.content.received{
font-weight:normal;
}
#comments table.event_comments{
/*width:800px;*/
}
#comments table.event_comments td{
padding:3px;
background-color:#ccc;
}
#comments .event th{
text-align:left;
}
#comments .event td{
padding:3px;
border-right:1px solid #fff;
}
#comments .event button{
text-align:right;
}
#comments .event_start{
width:200px;
text-align:center;
}
#comments .event_title{
width:400px;
}
#comments .event_show_comments{
height:2em;
}
#comments .event_excerpt{
}
#content #comments td.content{
width:100%;
}

View File

@@ -0,0 +1,125 @@
td,th,input {
line-height:100%;
ffont-size:10px;
}
td,th{
display:table-cell;
font-weight:normal;
}
td.level0, td.level1, td.level2, td.level3, td.level4, td.level5{
opacity:0.8;
border:0;
}
td.host{
color:gray;
}
td.level0{
padding-left:0px;
}
td.level1{
padding-left:20px;
}
td.level2{
padding-left:40px;
}
td.level3{
padding-left:60px;
}
td.level4{
padding-left:80px;
}
td.level5{
padding-left:100px;
}
img.level0{
margin-left:0px;
}
img.level1{
margin-left:20px;
}
img.level2{
margin-left:40px;
}
img.level3{
margin-left:60px;
}
img.level4{
margin-left:80px;
}
img.level5{
margin-left:100px;
}
tr{
vertical-align:middle;
}
tr.show{
color:#030;
text-decoration:none;
}
#content tr.show td{
padding-top:0px;
padding-bottom:0px;
}
tr.blocked{
color:#a33;
text-decoration:break-through;
}
td.content.unread{
font-weight:bold;
}
td.content.received{
font-weight:normal;
}
table.event_comments{
width:800px;
}
table.event_comments td{
padding:3px;
background-color:#ccc;
}
.event th{
text-align:left;
opacity:0.8;
}
.event td{
padding:3px;
border-right:1px solid #fff;
}
.event button{
text-align:right;
opacity:0.8;
}
.event_start{
width:200px;
text-align:center;
}
.event_title{
width:400px;
}
.event_show_comments{
height:2em;
}
.event_excerpt{
opacity:0.8;
}

View File

@@ -0,0 +1,49 @@
table.diff {
border-collapse: collapse;
border-top: solid 1px #999999;
border-left: solid 1px #999999;
}
table.diff td {
padding: 2px;
padding-left: 5px;
padding-right: 5px;
border-right: solid 1px #999999;
border-bottom: solid 1px #999999;
}
table.diff td:nth-child(1),
table.diff td:nth-child(2) {
background-color: #deedff;
}
table.diff tr.change,
table.diff tr.disc_a,
table.diff tr.disc_b {
background-color: #ffffdd;
}
table.diff tr.del {
background-color: #ffeeee;
}
table.diff tr.ins {
background-color: #eeffee;
}
table.diff td ins {
padding: 2px;
color: #009900;
background-color: #ccffcc;
text-decoration: none;
font-weight: bold;
}
table.diff td del {
padding: 2px;
color: #990000;
background-color: #ffcccc;
text-decoration: none;
font-weight: bold;
}

View File

@@ -0,0 +1,66 @@
pre{
white-space:pre-wrap;
}
#content div.editor div p a img {
float:right;
}
#content div.editor td{
width:800px;
padding-left:0;
}
#content div.editor td.label{
width:11em;
}
#content div.editor input.image{
width:90%;
}
#content .editor img{
padding:0;
margin:0;
border:none;
width:24px;
height:24px;
}
#content .edit_event input,
#content .edit_event select,
#content .edit_event textarea{
padding:0.5em;
}
#content .excerpt{
width:100%;
height:3em;
}
#content textarea{
width:100%;
}
#content .edit_event input.url{
width:100%;
}
#content .panel{
margin:1em;
border:1px solid #ccc;
}
.date{
width:10em;
}
.time{
width:6em;
}
.episode{
width:3em;
}

View File

@@ -0,0 +1,46 @@
#px_display {
padding-top: 10px;
padding-bottom: 10px;
}
.uploadData {
padding: 5px;
width: 420px;
margin-top: 5px;
margin-bottom: 5px;
background-color: #F0F8FF;
border: 1px solid #B0D8FF;
position: relative;
}
.uploadData .fname {
padding-right: 10px;
width: 120px;
}
.uploadData .loader {
width: 140px;
text-align: center;
border-bottom-width: 1px;
border-bottom-style: dotted;
border-bottom-color: #999999;
}
.uploadData .result {
display: block;
float: left;
width: 130px;
padding-left: 10px;
}
.uploadData .close {
background-image: url(close.gif);
height: 16px;
width: 16px;
position: absolute;
top: 5px;
right: 5px;
cursor: pointer;
}
.uploadData .close:hover {
background-position: 16px 0px;
}
#px_button input{
margin-right: 6px;
padding: 5px;
}

View File

@@ -0,0 +1,48 @@
#content div.image{
display:inline-block;
vertical-alignment:top;
border:1px solid gray;
margin:6px;
padding:0;
text-align:left;
background-repeat:no-repeat;
width:150px;
height:150px;
vertical-align:bottom;
}
#content .image_detail{
width:150px;
height:150px;
}
#content .close{
text-align:right;
padding:0;
margin:0;
color:white;
float:right;
}
form table{
width:100%;
height:100%;
}
input.field{
width:30em;
}
#content div.image .label{
text-align:center;
background-color:#333;
color:#fff;
vertical-align:bottom;
opacity:0.8;
padding:6px;
width:138px;
margin:0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -0,0 +1,30 @@
.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
.ui-timepicker-div dl { text-align: left; }
.ui-timepicker-div dl dt { float: left; clear:left; padding: 0 0 0 5px; }
.ui-timepicker-div dl dd { margin: 0 10px 10px 40%; }
.ui-timepicker-div td { font-size: 90%; }
.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
.ui-timepicker-div .ui_tpicker_unit_hide{ display: none; }
.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input { background: none; color: inherit; border: none; outline: none; border-bottom: solid 1px #555; width: 95%; }
.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input:focus { border-bottom-color: #aaa; }
.ui-timepicker-rtl{ direction: rtl; }
.ui-timepicker-rtl dl { text-align: right; padding: 0 5px 0 0; }
.ui-timepicker-rtl dl dt{ float: right; clear: right; }
.ui-timepicker-rtl dl dd { margin: 0 40% 10px 10px; }
/* Shortened version style */
.ui-timepicker-div.ui-timepicker-oneLine { padding-right: 2px; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,
.ui-timepicker-div.ui-timepicker-oneLine dt { display: none; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time_label { display: block; padding-top: 2px; }
.ui-timepicker-div.ui-timepicker-oneLine dl { text-align: right; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd,
.ui-timepicker-div.ui-timepicker-oneLine dl dd > div { display:inline-block; margin:0; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_minute:before,
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_second:before { content:':'; display:inline-block; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_millisec:before,
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_microsec:before { content:'.'; display:inline-block; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide,
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide:before{ display: none; }

View File

@@ -0,0 +1,11 @@
.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
.ui-timepicker-div dl { text-align: left; }
.ui-timepicker-div dl dt { float: left; clear:left; padding: 0 0 0 5px; }
.ui-timepicker-div dl dd { margin: 0 10px 10px 40%; }
.ui-timepicker-div td { font-size: 90%; }
.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
.ui-timepicker-rtl{ direction: rtl; }
.ui-timepicker-rtl dl { text-align: right; padding: 0 5px 0 0; }
.ui-timepicker-rtl dl dt{ float: right; clear: right; }
.ui-timepicker-rtl dl dd { margin: 0 40% 10px 10px; }

1312
website/agenda/planung/css/jquery-ui.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,833 @@
/*!
* jQuery UI CSS Framework 1.11.4
* http://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* http://api.jqueryui.com/category/theming/
*/
/* Layout helpers
----------------------------------*/
.ui-helper-hidden {
display: none;
}
.ui-helper-hidden-accessible {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.ui-helper-reset {
margin: 0;
padding: 0;
border: 0;
outline: 0;
line-height: 1.3;
text-decoration: none;
font-size: 100%;
list-style: none;
}
.ui-helper-clearfix:before,
.ui-helper-clearfix:after {
content: "";
display: table;
border-collapse: collapse;
}
.ui-helper-clearfix:after {
clear: both;
}
.ui-helper-clearfix {
min-height: 0; /* support: IE7 */
}
.ui-helper-zfix {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: absolute;
opacity: 0;
filter:Alpha(Opacity=0); /* support: IE8 */
}
.ui-front {
z-index: 100;
}
/* Interaction Cues
----------------------------------*/
.ui-state-disabled {
cursor: default !important;
}
/* Icons
----------------------------------*/
/* states and images */
.ui-icon {
display: block;
text-indent: -99999px;
overflow: hidden;
background-repeat: no-repeat;
}
/* Misc visuals
----------------------------------*/
/* Overlays */
.ui-widget-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.ui-draggable-handle {
-ms-touch-action: none;
touch-action: none;
}
.ui-resizable {
position: relative;
}
.ui-resizable-handle {
position: absolute;
font-size: 0.1px;
display: block;
-ms-touch-action: none;
touch-action: none;
}
.ui-resizable-disabled .ui-resizable-handle,
.ui-resizable-autohide .ui-resizable-handle {
display: none;
}
.ui-resizable-n {
cursor: n-resize;
height: 7px;
width: 100%;
top: -5px;
left: 0;
}
.ui-resizable-s {
cursor: s-resize;
height: 7px;
width: 100%;
bottom: -5px;
left: 0;
}
.ui-resizable-e {
cursor: e-resize;
width: 7px;
right: -5px;
top: 0;
height: 100%;
}
.ui-resizable-w {
cursor: w-resize;
width: 7px;
left: -5px;
top: 0;
height: 100%;
}
.ui-resizable-se {
cursor: se-resize;
width: 12px;
height: 12px;
right: 1px;
bottom: 1px;
}
.ui-resizable-sw {
cursor: sw-resize;
width: 9px;
height: 9px;
left: -5px;
bottom: -5px;
}
.ui-resizable-nw {
cursor: nw-resize;
width: 9px;
height: 9px;
left: -5px;
top: -5px;
}
.ui-resizable-ne {
cursor: ne-resize;
width: 9px;
height: 9px;
right: -5px;
top: -5px;
}
.ui-selectable {
-ms-touch-action: none;
touch-action: none;
}
.ui-selectable-helper {
position: absolute;
z-index: 100;
border: 1px dotted black;
}
.ui-sortable-handle {
-ms-touch-action: none;
touch-action: none;
}
.ui-accordion .ui-accordion-header {
display: block;
cursor: pointer;
position: relative;
margin: 2px 0 0 0;
padding: .5em .5em .5em .7em;
min-height: 0; /* support: IE7 */
font-size: 100%;
}
.ui-accordion .ui-accordion-icons {
padding-left: 2.2em;
}
.ui-accordion .ui-accordion-icons .ui-accordion-icons {
padding-left: 2.2em;
}
.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
position: absolute;
left: .5em;
top: 50%;
margin-top: -8px;
}
.ui-accordion .ui-accordion-content {
padding: 1em 2.2em;
border-top: 0;
overflow: auto;
}
.ui-autocomplete {
position: absolute;
top: 0;
left: 0;
cursor: default;
}
.ui-button {
display: inline-block;
position: relative;
padding: 0;
line-height: normal;
margin-right: .1em;
cursor: pointer;
vertical-align: middle;
text-align: center;
overflow: visible; /* removes extra width in IE */
}
.ui-button,
.ui-button:link,
.ui-button:visited,
.ui-button:hover,
.ui-button:active {
text-decoration: none;
}
/* to make room for the icon, a width needs to be set here */
.ui-button-icon-only {
width: 2.2em;
}
/* button elements seem to need a little more width */
button.ui-button-icon-only {
width: 2.4em;
}
.ui-button-icons-only {
width: 3.4em;
}
button.ui-button-icons-only {
width: 3.7em;
}
/* button text element */
.ui-button .ui-button-text {
display: block;
line-height: normal;
}
.ui-button-text-only .ui-button-text {
padding: .4em 1em;
}
.ui-button-icon-only .ui-button-text,
.ui-button-icons-only .ui-button-text {
padding: .4em;
text-indent: -9999999px;
}
.ui-button-text-icon-primary .ui-button-text,
.ui-button-text-icons .ui-button-text {
padding: .4em 1em .4em 2.1em;
}
.ui-button-text-icon-secondary .ui-button-text,
.ui-button-text-icons .ui-button-text {
padding: .4em 2.1em .4em 1em;
}
.ui-button-text-icons .ui-button-text {
padding-left: 2.1em;
padding-right: 2.1em;
}
/* no icon support for input elements, provide padding by default */
input.ui-button {
padding: .4em 1em;
}
/* button icon element(s) */
.ui-button-icon-only .ui-icon,
.ui-button-text-icon-primary .ui-icon,
.ui-button-text-icon-secondary .ui-icon,
.ui-button-text-icons .ui-icon,
.ui-button-icons-only .ui-icon {
position: absolute;
top: 50%;
margin-top: -8px;
}
.ui-button-icon-only .ui-icon {
left: 50%;
margin-left: -8px;
}
.ui-button-text-icon-primary .ui-button-icon-primary,
.ui-button-text-icons .ui-button-icon-primary,
.ui-button-icons-only .ui-button-icon-primary {
left: .5em;
}
.ui-button-text-icon-secondary .ui-button-icon-secondary,
.ui-button-text-icons .ui-button-icon-secondary,
.ui-button-icons-only .ui-button-icon-secondary {
right: .5em;
}
/* button sets */
.ui-buttonset {
margin-right: 7px;
}
.ui-buttonset .ui-button {
margin-left: 0;
margin-right: -.3em;
}
/* workarounds */
/* reset extra padding in Firefox, see h5bp.com/l */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
border: 0;
padding: 0;
}
.ui-datepicker {
width: 17em;
padding: .2em .2em 0;
display: none;
}
.ui-datepicker .ui-datepicker-header {
position: relative;
padding: .2em 0;
}
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-next {
position: absolute;
top: 2px;
width: 1.8em;
height: 1.8em;
}
.ui-datepicker .ui-datepicker-prev-hover,
.ui-datepicker .ui-datepicker-next-hover {
top: 1px;
}
.ui-datepicker .ui-datepicker-prev {
left: 2px;
}
.ui-datepicker .ui-datepicker-next {
right: 2px;
}
.ui-datepicker .ui-datepicker-prev-hover {
left: 1px;
}
.ui-datepicker .ui-datepicker-next-hover {
right: 1px;
}
.ui-datepicker .ui-datepicker-prev span,
.ui-datepicker .ui-datepicker-next span {
display: block;
position: absolute;
left: 50%;
margin-left: -8px;
top: 50%;
margin-top: -8px;
}
.ui-datepicker .ui-datepicker-title {
margin: 0 2.3em;
line-height: 1.8em;
text-align: center;
}
.ui-datepicker .ui-datepicker-title select {
font-size: 1em;
margin: 1px 0;
}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year {
width: 45%;
}
.ui-datepicker table {
width: 100%;
font-size: .9em;
border-collapse: collapse;
margin: 0 0 .4em;
}
.ui-datepicker th {
padding: .7em .3em;
text-align: center;
font-weight: bold;
border: 0;
}
.ui-datepicker td {
border: 0;
padding: 1px;
}
.ui-datepicker td span,
.ui-datepicker td a {
display: block;
padding: .2em;
text-align: right;
text-decoration: none;
}
.ui-datepicker .ui-datepicker-buttonpane {
background-image: none;
margin: .7em 0 0 0;
padding: 0 .2em;
border-left: 0;
border-right: 0;
border-bottom: 0;
}
.ui-datepicker .ui-datepicker-buttonpane button {
float: right;
margin: .5em .2em .4em;
cursor: pointer;
padding: .2em .6em .3em .6em;
width: auto;
overflow: visible;
}
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
float: left;
}
/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi {
width: auto;
}
.ui-datepicker-multi .ui-datepicker-group {
float: left;
}
.ui-datepicker-multi .ui-datepicker-group table {
width: 95%;
margin: 0 auto .4em;
}
.ui-datepicker-multi-2 .ui-datepicker-group {
width: 50%;
}
.ui-datepicker-multi-3 .ui-datepicker-group {
width: 33.3%;
}
.ui-datepicker-multi-4 .ui-datepicker-group {
width: 25%;
}
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
border-left-width: 0;
}
.ui-datepicker-multi .ui-datepicker-buttonpane {
clear: left;
}
.ui-datepicker-row-break {
clear: both;
width: 100%;
font-size: 0;
}
/* RTL support */
.ui-datepicker-rtl {
direction: rtl;
}
.ui-datepicker-rtl .ui-datepicker-prev {
right: 2px;
left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next {
left: 2px;
right: auto;
}
.ui-datepicker-rtl .ui-datepicker-prev:hover {
right: 1px;
left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next:hover {
left: 1px;
right: auto;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane {
clear: right;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button {
float: left;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
.ui-datepicker-rtl .ui-datepicker-group {
float: right;
}
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
border-right-width: 0;
border-left-width: 1px;
}
.ui-dialog {
overflow: hidden;
position: absolute;
top: 0;
left: 0;
padding: .2em;
outline: 0;
}
.ui-dialog .ui-dialog-titlebar {
padding: .4em 1em;
position: relative;
}
.ui-dialog .ui-dialog-title {
float: left;
margin: .1em 0;
white-space: nowrap;
width: 90%;
overflow: hidden;
text-overflow: ellipsis;
}
.ui-dialog .ui-dialog-titlebar-close {
position: absolute;
right: .3em;
top: 50%;
width: 20px;
margin: -10px 0 0 0;
padding: 1px;
height: 20px;
}
.ui-dialog .ui-dialog-content {
position: relative;
border: 0;
padding: .5em 1em;
background: none;
overflow: auto;
}
.ui-dialog .ui-dialog-buttonpane {
text-align: left;
border-width: 1px 0 0 0;
background-image: none;
margin-top: .5em;
padding: .3em 1em .5em .4em;
}
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
float: right;
}
.ui-dialog .ui-dialog-buttonpane button {
margin: .5em .4em .5em 0;
cursor: pointer;
}
.ui-dialog .ui-resizable-se {
width: 12px;
height: 12px;
right: -5px;
bottom: -5px;
background-position: 16px 16px;
}
.ui-draggable .ui-dialog-titlebar {
cursor: move;
}
.ui-menu {
list-style: none;
padding: 0;
margin: 0;
display: block;
outline: none;
}
.ui-menu .ui-menu {
position: absolute;
}
.ui-menu .ui-menu-item {
position: relative;
margin: 0;
padding: 3px 1em 3px .4em;
cursor: pointer;
min-height: 0; /* support: IE7 */
/* support: IE10, see #8844 */
list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
}
.ui-menu .ui-menu-divider {
margin: 5px 0;
height: 0;
font-size: 0;
line-height: 0;
border-width: 1px 0 0 0;
}
.ui-menu .ui-state-focus,
.ui-menu .ui-state-active {
margin: -1px;
}
/* icon support */
.ui-menu-icons {
position: relative;
}
.ui-menu-icons .ui-menu-item {
padding-left: 2em;
}
/* left-aligned */
.ui-menu .ui-icon {
position: absolute;
top: 0;
bottom: 0;
left: .2em;
margin: auto 0;
}
/* right-aligned */
.ui-menu .ui-menu-icon {
left: auto;
right: 0;
}
.ui-progressbar {
height: 2em;
text-align: left;
overflow: hidden;
}
.ui-progressbar .ui-progressbar-value {
margin: -1px;
height: 100%;
}
.ui-progressbar .ui-progressbar-overlay {
background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
height: 100%;
filter: alpha(opacity=25); /* support: IE8 */
opacity: 0.25;
}
.ui-progressbar-indeterminate .ui-progressbar-value {
background-image: none;
}
.ui-selectmenu-menu {
padding: 0;
margin: 0;
position: absolute;
top: 0;
left: 0;
display: none;
}
.ui-selectmenu-menu .ui-menu {
overflow: auto;
/* Support: IE7 */
overflow-x: hidden;
padding-bottom: 1px;
}
.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
font-size: 1em;
font-weight: bold;
line-height: 1.5;
padding: 2px 0.4em;
margin: 0.5em 0 0 0;
height: auto;
border: 0;
}
.ui-selectmenu-open {
display: block;
}
.ui-selectmenu-button {
display: inline-block;
overflow: hidden;
position: relative;
text-decoration: none;
cursor: pointer;
}
.ui-selectmenu-button span.ui-icon {
right: 0.5em;
left: auto;
margin-top: -8px;
position: absolute;
top: 50%;
}
.ui-selectmenu-button span.ui-selectmenu-text {
text-align: left;
padding: 0.4em 2.1em 0.4em 1em;
display: block;
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.ui-slider {
position: relative;
text-align: left;
}
.ui-slider .ui-slider-handle {
position: absolute;
z-index: 2;
width: 1.2em;
height: 1.2em;
cursor: default;
-ms-touch-action: none;
touch-action: none;
}
.ui-slider .ui-slider-range {
position: absolute;
z-index: 1;
font-size: .7em;
display: block;
border: 0;
background-position: 0 0;
}
/* support: IE8 - See #6727 */
.ui-slider.ui-state-disabled .ui-slider-handle,
.ui-slider.ui-state-disabled .ui-slider-range {
filter: inherit;
}
.ui-slider-horizontal {
height: .8em;
}
.ui-slider-horizontal .ui-slider-handle {
top: -.3em;
margin-left: -.6em;
}
.ui-slider-horizontal .ui-slider-range {
top: 0;
height: 100%;
}
.ui-slider-horizontal .ui-slider-range-min {
left: 0;
}
.ui-slider-horizontal .ui-slider-range-max {
right: 0;
}
.ui-slider-vertical {
width: .8em;
height: 100px;
}
.ui-slider-vertical .ui-slider-handle {
left: -.3em;
margin-left: 0;
margin-bottom: -.6em;
}
.ui-slider-vertical .ui-slider-range {
left: 0;
width: 100%;
}
.ui-slider-vertical .ui-slider-range-min {
bottom: 0;
}
.ui-slider-vertical .ui-slider-range-max {
top: 0;
}
.ui-spinner {
position: relative;
display: inline-block;
overflow: hidden;
padding: 0;
vertical-align: middle;
}
.ui-spinner-input {
border: none;
background: none;
color: inherit;
padding: 0;
margin: .2em 0;
vertical-align: middle;
margin-left: .4em;
margin-right: 22px;
}
.ui-spinner-button {
width: 16px;
height: 50%;
font-size: .5em;
padding: 0;
margin: 0;
text-align: center;
position: absolute;
cursor: default;
display: block;
overflow: hidden;
right: 0;
}
/* more specificity required here to override default borders */
.ui-spinner a.ui-spinner-button {
border-top: none;
border-bottom: none;
border-right: none;
}
/* vertically center icon */
.ui-spinner .ui-icon {
position: absolute;
margin-top: -8px;
top: 50%;
left: 0;
}
.ui-spinner-up {
top: 0;
}
.ui-spinner-down {
bottom: 0;
}
/* TR overrides */
.ui-spinner .ui-icon-triangle-1-s {
/* need to fix icons sprite */
background-position: -65px -16px;
}
.ui-tabs {
position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
padding: .2em;
}
.ui-tabs .ui-tabs-nav {
margin: 0;
padding: .2em .2em 0;
}
.ui-tabs .ui-tabs-nav li {
list-style: none;
float: left;
position: relative;
top: 0;
margin: 1px .2em 0 0;
border-bottom-width: 0;
padding: 0;
white-space: nowrap;
}
.ui-tabs .ui-tabs-nav .ui-tabs-anchor {
float: left;
padding: .5em 1em;
text-decoration: none;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active {
margin-bottom: -1px;
padding-bottom: 1px;
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
cursor: text;
}
.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
cursor: pointer;
}
.ui-tabs .ui-tabs-panel {
display: block;
border-width: 0;
padding: 1em 1.4em;
background: none;
}
.ui-tooltip {
padding: 8px;
position: absolute;
z-index: 9999;
max-width: 300px;
-webkit-box-shadow: 0 0 5px #aaa;
box-shadow: 0 0 5px #aaa;
}
body .ui-tooltip {
border-width: 2px;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,410 @@
/*!
* jQuery UI CSS Framework 1.11.4
* http://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* http://api.jqueryui.com/category/theming/
*
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
*/
/* Component containers
----------------------------------*/
.ui-widget {
font-family: Verdana,Arial,sans-serif;
font-size: 1.1em;
}
.ui-widget .ui-widget {
font-size: 1em;
}
.ui-widget input,
.ui-widget select,
.ui-widget textarea,
.ui-widget button {
font-family: Verdana,Arial,sans-serif;
font-size: 1em;
}
.ui-widget-content {
border: 1px solid #aaaaaa;
background: #ffffff;
color: #222222;
}
.ui-widget-content a {
color: #222222;
}
.ui-widget-header {
border: 1px solid #aaaaaa;
background: #cccccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;
color: #222222;
font-weight: bold;
}
.ui-widget-header a {
color: #222222;
}
/* Interaction states
----------------------------------*/
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default {
border: 1px solid #d3d3d3;
background: #e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;
font-weight: normal;
color: #555555;
}
.ui-state-default a,
.ui-state-default a:link,
.ui-state-default a:visited {
color: #555555;
text-decoration: none;
}
.ui-state-hover,
.ui-widget-content .ui-state-hover,
.ui-widget-header .ui-state-hover,
.ui-state-focus,
.ui-widget-content .ui-state-focus,
.ui-widget-header .ui-state-focus {
border: 1px solid #999999;
background: #dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;
font-weight: normal;
color: #212121;
}
.ui-state-hover a,
.ui-state-hover a:hover,
.ui-state-hover a:link,
.ui-state-hover a:visited,
.ui-state-focus a,
.ui-state-focus a:hover,
.ui-state-focus a:link,
.ui-state-focus a:visited {
color: #212121;
text-decoration: none;
}
.ui-state-active,
.ui-widget-content .ui-state-active,
.ui-widget-header .ui-state-active {
border: 1px solid #aaaaaa;
background: #ffffff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
font-weight: normal;
color: #212121;
}
.ui-state-active a,
.ui-state-active a:link,
.ui-state-active a:visited {
color: #212121;
text-decoration: none;
}
/* Interaction Cues
----------------------------------*/
.ui-state-highlight,
.ui-widget-content .ui-state-highlight,
.ui-widget-header .ui-state-highlight {
border: 1px solid #fcefa1;
background: #fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;
color: #363636;
}
.ui-state-highlight a,
.ui-widget-content .ui-state-highlight a,
.ui-widget-header .ui-state-highlight a {
color: #363636;
}
.ui-state-error,
.ui-widget-content .ui-state-error,
.ui-widget-header .ui-state-error {
border: 1px solid #cd0a0a;
background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;
color: #cd0a0a;
}
.ui-state-error a,
.ui-widget-content .ui-state-error a,
.ui-widget-header .ui-state-error a {
color: #cd0a0a;
}
.ui-state-error-text,
.ui-widget-content .ui-state-error-text,
.ui-widget-header .ui-state-error-text {
color: #cd0a0a;
}
.ui-priority-primary,
.ui-widget-content .ui-priority-primary,
.ui-widget-header .ui-priority-primary {
font-weight: bold;
}
.ui-priority-secondary,
.ui-widget-content .ui-priority-secondary,
.ui-widget-header .ui-priority-secondary {
opacity: .7;
filter:Alpha(Opacity=70); /* support: IE8 */
font-weight: normal;
}
.ui-state-disabled,
.ui-widget-content .ui-state-disabled,
.ui-widget-header .ui-state-disabled {
opacity: .35;
filter:Alpha(Opacity=35); /* support: IE8 */
background-image: none;
}
.ui-state-disabled .ui-icon {
filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
}
/* Icons
----------------------------------*/
/* states and images */
.ui-icon {
width: 16px;
height: 16px;
}
.ui-icon,
.ui-widget-content .ui-icon {
background-image: url("images/ui-icons_222222_256x240.png");
}
.ui-widget-header .ui-icon {
background-image: url("images/ui-icons_222222_256x240.png");
}
.ui-state-default .ui-icon {
background-image: url("images/ui-icons_888888_256x240.png");
}
.ui-state-hover .ui-icon,
.ui-state-focus .ui-icon {
background-image: url("images/ui-icons_454545_256x240.png");
}
.ui-state-active .ui-icon {
background-image: url("images/ui-icons_454545_256x240.png");
}
.ui-state-highlight .ui-icon {
background-image: url("images/ui-icons_2e83ff_256x240.png");
}
.ui-state-error .ui-icon,
.ui-state-error-text .ui-icon {
background-image: url("images/ui-icons_cd0a0a_256x240.png");
}
/* positioning */
.ui-icon-blank { background-position: 16px 16px; }
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -96px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-on { background-position: -96px -144px; }
.ui-icon-radio-off { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
/* Misc visuals
----------------------------------*/
/* Corner radius */
.ui-corner-all,
.ui-corner-top,
.ui-corner-left,
.ui-corner-tl {
border-top-left-radius: 4px;
}
.ui-corner-all,
.ui-corner-top,
.ui-corner-right,
.ui-corner-tr {
border-top-right-radius: 4px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-left,
.ui-corner-bl {
border-bottom-left-radius: 4px;
}
.ui-corner-all,
.ui-corner-bottom,
.ui-corner-right,
.ui-corner-br {
border-bottom-right-radius: 4px;
}
/* Overlays */
.ui-widget-overlay {
background: #aaaaaa;
opacity: .3;
filter: Alpha(Opacity=30); /* support: IE8 */
}
.ui-widget-shadow {
margin: -8px 0 0 -8px;
padding: 8px;
background: #aaaaaa;
opacity: .3;
filter: Alpha(Opacity=30); /* support: IE8 */
border-radius: 8px;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,49 @@
h2{
display:inline;
}
#content{
height:1000px;
}
div#oldSeries{
clear:both;
}
div#newSeries, div#oldSeries{
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
div#newSeries div,
div#oldSeries div{
color:#fff;
background:#1abc9c;
padding:6px;
padding-top:6px;
margin:6px;
margin-left:6px;
margin-right:6px;
/*float:left;*/
cursor:pointer;
text-align:center;
display:table-cell;
vertical-align:middle;
width:10rem;
height:3rem;
line-height:2em;
}
/*
*/
div#newSeries div:hover,
div#oldSeries div:hover{
background:#1dd2af;
}
div#search{
float:right;
}

View File

@@ -0,0 +1,21 @@
table{
padding:0;
margin:1em;
border-collapse:collapse;
empty-cells:show;
}
tr{
margin:0;
padding:0;
border-top:1px solid #666;
}
td{
min-width:10em;
padding:3px;
margin:0;
font-size:-2;
}

View File

@@ -0,0 +1,44 @@
#content .label{
width:10em;
padding:0;
margin:0;
color:#555;
}
#content div.project{
width:45%;
}
#content div.editor{
clear:both;
}
#content div.view{
clear:both;
}
#content div.view img{
max-width:50px;
max-height:50px;
}
#content div.editor div.right{
float:right;
padding:0;
margin:0;
}
#content div.editor div.buttons{
text-align:center;
padding:0;
}
#content div.editor div.buttons button,
#content div.editor div.buttons input{
margin-left:1em;
}
#content div.view{
text-align:left;
}

View File

@@ -0,0 +1,298 @@
#content{
margin-top:3em;
padding:1em;
max-width:1000px;
min-height:100%;
}
#content td.label{
max-width:3em;
}
#content .label{
padding:0;
margin:0;
color:#555;
}
#content table.series{
border-radius:1em;
}
#content .series div.header{
font-weight:bold;
cursor:pointer;
}
#content div.header{
clear:both;
}
#content .right{
float:right;
padding:0;
margin:0;
}
#content .editor{
clear:both;
}
#content .editor div.buttons{
text-align:center;
padding:0;
}
#content .editor div.buttons button,
#content .editor div.buttons input{
margin-left:1em;
}
/*
#content .editor input,
#content .editor textarea,
#content .editor button{
padding:6px;
}
*/
#imagePreview{
padding:0;
margin:0;
border:none;
width:24px;
height:24px;
}
#context textarea{
width:600px;
height:100px;
}
#content table.series {
border:1px solid #ddd;
}
#content table.series table{
width:100%;
}
#content table.series tr:nth-child(4n+1){
background-color:#eee;
}
#content table.series tr.active td{
background-color: #aaa;
}
#content .series table tr{
padding:0;
margin:0;
}
#content .series table td:nth-child(1){
width:10em;
}
#content .series table td{
padding:6px;
margin:0;
}
#content .editor .row{
clear:both;
min-height:4em;
}
#content .editor .cell{
float:left;
text-align:center;
white-space:nowrap;
}
#content .editor .row.active{
background:#ff0;
min-height:4em;
}
#content div.ui-tabs-panel,
#content div.editor,
#content div.row.schedule{
padding-left:0;
padding-right:0;
}
/* start of schedule */
#content div.cell{
margin-left:6px;
margin-right:0;
padding-left:0;
padding-right:0;
}
#content div.cell.exclude,
#content div.cell.nextDay,
#content div.cell.weekday{
margin-left:0;
}
#content div.cell.containsInput{
margin-right:12px;
}
#content div.cell.containsSelect{
margin-right:12px;
}
#content div.cell.exclude,
#content div.cell.nextDay{
width:1em;
}
#content div.cell.weekday,
#content div.cell.weekday input,
#content div.cell.weekday select{
width:2em;
padding-top:2em;
}
#content div.cell.start,
#content div.cell.start input,
#content div.cell.start select{
width:9.5em;
}
#content div.cell.duration,
#content div.cell.duration input,
#content div.cell.duration select{
width:7em;
}
#content div.cell.period_type,
#content div.cell.period_type input,
#content div.cell.period_type select{
width:7em;
}
#content div.cell.period_type.isSingle,
#content div.cell.period_type select.isSingle{
width:9em;
}
#content div.cell.end,
#content div.cell.end input,
#content div.cell.end select{
width:6em;
}
#content div.cell.frequency,
#content div.cell.frequency input,
#content div.cell.frequency select{
width:6em;
}
#content div.cell.week_of_month,
#content div.cell.week_of_month input,
#content div.cell.week_of_month select{
width:6em;
}
#content div.cell.schedule_weekday,
#content div.cell.schedule_weekday input,
#content div.cell.schedule_weekday select{
width:4em;
}
#content div.cell.schedule_month,
#content div.cell.schedule_month input,
#content div.cell.schedule_month select{
width:6em;
}
/* end of schedule */
#content .create_events{
width:5em;
}
#content .publish_events{
width:5em;
}
#content div.show_schedule{
overflow:auto;
height:20em;
clear:both;
}
#content div.show_schedule table{
width:24em;
}
#content div.show_schedule td{
width:10em;
}
#content div.show_schedule td:nth-child(1){
width:2em;
}
/*
#content div.show_schedule tr:nth-child(odd){
background:#f0f0f0;
}
*/
#content div.show_schedule tr.exclude td{
text-decoration:line-through;
}
#content div.buttons{
padding-left:12px;
}
#content div.editor input.image{
width:90%;
}
#content #tabs-events td.weekday,
#content #tabs-events td.date,
#content #tabs-events td.time,
#content #tabs-events td.spacer{
width:0;
}
#content #tabs-events td.weekday,
#content #tabs-events td.spacer{
padding:0;
}
#content input.datetimepicker{
padding-left:0;
padding-right:0;
}
button{
cursor:pointer;
}
form{
padding:0;
margin:0;
}
@media print {
input,button{
display:none;
}
}
/*
#content .editor .row:nth-child(2n+1){
background:#eee;
}
*/

View File

@@ -0,0 +1,114 @@
#content{
margin-top:3em;
padding:1em;
max-width:1000px;
min-height:100%;
}
#content .label{
padding:0;
margin:0;
color:#555;
}
#content div.header{
clear:both;
}
#content .right{
float:right;
padding:0;
margin:0;
}
#content .editor{
clear:both;
}
#content .editor div.buttons{
text-align:center;
padding:0;
}
#content .editor div.buttons button,
#content .editor div.buttons input{
margin-left:1em;
}
#content .editor input,
#content .editor textarea,
#content .editor button{
padding:6px;
}
#content .editor .row{
clear:both;
}
#content .editor .cell{
float:left;
text-align:center;
}
#content .frequency{
width:6em;
}
#content div.weekday{
padding:0;
width:2em;
margin-right:-0.5em;
margin-top:1.2em;
}
#content div.show_schedule_head{
clear:both;
}
#content div.show_schedule{
clear:both;
}
#content div.show_schedule table{
width:66%;
}
#content div.show_schedule td{
width:10em;
}
/* weekday start*/
#content div.show_schedule td:nth-child(1){
width:2em;
}
/* weekday end*/
#content div.show_schedule td:nth-child(3){
width:2em;
}
#content div.show_schedule tr.exclude td{
text-decoration:line-through;
}
#content div.buttons{
padding-left:12px;
}
#content div.editor input.image{
width:90%;
}
button{
cursor:pointer;
}
form{
padding:0;
margin:0;
}
@media print {
input,button{
display:none;
}
}

View File

@@ -0,0 +1,36 @@
#content .label{
width:10em;
padding:0;
margin:0;
color:#555;
}
#content div.studio{
min-width:40%;
}
#content div.editor{
display:inline-block;
}
#content div.editor div.right{
float:right;
padding:0;
margin:0;
}
#content div.editor div.buttons{
text-align:center;
padding:0;
}
#content div.editor div.buttons button,
#content div.editor div.buttons input{
margin-left:1em;
}
#content div.view{
text-align:left;
clear:both;
}

View File

@@ -0,0 +1,205 @@
/*************
Default Theme
*************/
/* overall */
/*
.tablesorter-default {
width: 100%;
font: 12px/18px Arial, Sans-serif;
color: #333;
background-color: #fff;
border-spacing: 0;
margin: 10px 0 15px;
text-align: left;
}
*/
/* header */
/*
.tablesorter-default th,
.tablesorter-default thead td {
font: bold 12px/18px Arial, Sans-serif;
color: #000;
background-color: #fff;
border-collapse: collapse;
border-bottom: #ccc 2px solid;
padding: 0;
}
.tablesorter-default tfoot th,
.tablesorter-default tfoot td {
border: 0;
}
*/
.tablesorter-default .header,
.tablesorter-default .tablesorter-header {
background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
background-position: center right;
background-repeat: no-repeat;
cursor: pointer;
white-space: normal;
padding: 4px 20px 4px 4px;
}
.tablesorter-default thead .headerSortUp,
.tablesorter-default thead .tablesorter-headerSortUp,
.tablesorter-default thead .tablesorter-headerAsc {
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
/*
border-bottom: #000 2px solid;
*/
}
.tablesorter-default thead .headerSortDown,
.tablesorter-default thead .tablesorter-headerSortDown,
.tablesorter-default thead .tablesorter-headerDesc {
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
/*
border-bottom: #000 2px solid;
*/
}
.tablesorter-default thead .sorter-false {
background-image: none;
cursor: default;
padding: 4px;
}
/* tfoot */
/*
.tablesorter-default tfoot .tablesorter-headerSortUp,
.tablesorter-default tfoot .tablesorter-headerSortDown,
.tablesorter-default tfoot .tablesorter-headerAsc,
.tablesorter-default tfoot .tablesorter-headerDesc {
border-top: #000 2px solid;
}
*/
/* tbody */
/*
.tablesorter-default td {
background-color: #fff;
border-bottom: #ccc 1px solid;
padding: 4px;
vertical-align: top;
}
*/
/* hovered row colors */
/*
.tablesorter-default tbody > tr:hover > td,
.tablesorter-default tbody > tr.even:hover > td,
.tablesorter-default tbody > tr.odd:hover > td {
background: #fff;
color: #000;
}
*/
/* table processing indicator */
.tablesorter-default .tablesorter-processing {
background-position: center center !important;
background-repeat: no-repeat !important;
/* background-image: url(../addons/pager/icons/loading.gif) !important; */
background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important;
}
/* Zebra Widget - row alternating colors */
/*
.tablesorter-default tr.odd td {
background-color: #dfdfdf;
}
.tablesorter-default tr.even td {
background-color: #efefef;
}
*/
/* Column Widget - column sort colors */
/*
.tablesorter-default tr.odd td.primary {
background-color: #bfbfbf;
}
.tablesorter-default td.primary,
.tablesorter-default tr.even td.primary {
background-color: #d9d9d9;
}
.tablesorter-default tr.odd td.secondary {
background-color: #d9d9d9;
}
.tablesorter-default td.secondary,
.tablesorter-default tr.even td.secondary {
background-color: #e6e6e6;
}
.tablesorter-default tr.odd td.tertiary {
background-color: #e6e6e6;
}
.tablesorter-default td.tertiary,
.tablesorter-default tr.even td.tertiary {
background-color: #f2f2f2;
}
*/
/* caption */
caption {
background: #fff;
}
/* filter widget */
.tablesorter-default .tablesorter-filter-row td {
background: #eee;
border-bottom: #ccc 1px solid;
line-height: normal;
text-align: center; /* center the input */
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* optional disabled input styling */
.tablesorter-default .tablesorter-filter-row .disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: not-allowed;
}
/* hidden filter row */
.tablesorter-default .tablesorter-filter-row.hideme td {
/*** *********************************************** ***/
/*** change this padding to modify the thickness ***/
/*** of the closed filter row (height = padding x 2) ***/
padding: 2px;
/*** *********************************************** ***/
margin: 0;
line-height: 0;
cursor: pointer;
}
.tablesorter-default .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* filters */
.tablesorter-default .tablesorter-filter {
width: 95%;
height: auto;
margin: 4px;
padding: 4px;
background-color: #fff;
border: 1px solid #bbb;
color: #333;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}

View File

@@ -0,0 +1,5 @@
form table{
margin:6px;
padding:6px;
}

View File

@@ -0,0 +1,278 @@
body{
background:#666;
}
#content{
margin-top:3em;
padding:1em;
max-width:1000px;
min-height:100%;
}
#content td.label{
max-width:3em;
}
#content .label{
padding:0;
margin:0;
color:#555;
}
#content div.header{
clear:both;
}
#content .right{
float:right;
padding:0;
margin:0;
}
#content .editor{
clear:both;
}
#content .editor div.buttons{
text-align:center;
padding:0;
}
#content .editor div.buttons button,
#content .editor div.buttons input{
margin-left:1em;
}
#content .editor input,
#content .editor textarea,
#content .editor button{
padding:6px;
}
#context textarea{
width:600px;
height:100px;
}
#content table.series {
border:1px solid #ddd;
}
#content table.series table{
width:100%;
}
#content table.series tr:nth-child(4n+1){
background-color:#eee;
}
#content table.series tr.active td{
background-color: #aaa;
}
#content .series table tr{
padding:0;
margin:0;
}
#content .series table td:nth-child(1){
width:10em;
}
#content .series table td{
padding:6px;
margin:0;
}
#content .series table tr:nth-child(odd){
background:#eee;
}
#content .editor .row{
clear:both;
min-height:4em;
}
#content .editor .cell{
float:left;
text-align:center;
white-space:nowrap;
}
#content .editor .row.active{
background:#ff0;
min-height:4em;
}
#content .editor div.row.schedule.selected{
background:#ff0;
min-height:4em;
}
/*
#content .editor .row:nth-child(2n+1){
background:#eee;
}
*/
#content div.ui-tabs-panel,
#content div.editor,
#content div.row.schedule{
padding-left:0;
padding-right:0;
}
/* start of schedule */
#content div.cell{
margin-left:6px;
margin-right:0;
padding-left:0;
padding-right:0;
}
#content div.cell.exclude,
#content div.cell.weekday{
margin-left:0;
}
#content div.cell.containsInput{
margin-right:16px;
}
#content div.cell.containsSelect{
margin-right:16px;
}
#content div.cell.exclude{
width:1em;
}
#content div.cell.weekday,
#content div.cell.weekday input,
#content div.cell.weekday select{
width:2em;
padding-top:2em;
}
#content div.cell.start,
#content div.cell.start input,
#content div.cell.start select{
width:9em;
}
#content div.cell.duration,
#content div.cell.duration input,
#content div.cell.duration select{
width:7em;
}
#content div.cell.title,
#content div.cell.title input,
#content div.cell.title select{
width:6em;
}
#content div.cell.type,
#content div.cell.type input,
#content div.cell.type select{
width:6em;
}
#content div.cell.period_type,
#content div.cell.period_type input,
#content div.cell.period_type select{
width:7em;
}
#content div.cell.period_type.isSingle,
#content div.cell.period_type select.isSingle{
width:9em;
}
#content div.cell.end,
#content div.cell.end input,
#content div.cell.end select{
width:6em;
}
#content div.cell.frequency,
#content div.cell.frequency input,
#content div.cell.frequency select{
width:6em;
}
#content div.cell.week_of_month,
#content div.cell.week_of_month input,
#content div.cell.week_of_month select{
width:6em;
}
#content div.cell.schedule_weekday,
#content div.cell.schedule_weekday input,
#content div.cell.schedule_weekday select{
width:4em;
}
#content div.cell.schedule_month,
#content div.cell.schedule_month input,
#content div.cell.schedule_month select{
width:6em;
}
/* end of schedule */
#content div.show_schedule{
overflow:auto;
height:20em;
clear:both;
}
#content div.show_schedule table{
width:50em;
}
#content div.show_schedule td{
width:10em;
}
#content div.show_schedule td:nth-child(1){
width:2em;
}
#content div.show_schedule tr.exclude td{
text-decoration:line-through;
}
#content div.buttons{
padding-left:12px;
}
#content div.editor input.image{
width:90%;
}
button{
cursor:pointer;
}
form{
padding:0;
margin:0;
}
@media print {
input,button{
display:none;
}
}
/*
#content div.show_schedule tr:nth-child(odd){
background:#f0f0f0;
}
*/

View File

@@ -0,0 +1,85 @@
#! /usr/bin/perl -I../lib
use warnings "all";
use strict;
use Data::Dumper;
use HTML::Template;
#use URI::Escape;
#use Encode;
use config;
use log;
use template;
use params;
use config;
use auth;
use localization;
use studios;
binmode STDOUT, ":utf8";
my $r=shift;
(my $cgi, my $params, my $error)=params::get($r);
my $config = config::get('../config/config.cgi');
my $debug = $config->{system}->{debug};
my ($user, $expires) = auth::get_user($cgi, $config);
return if (!defined $user) || ($user eq '');
my $user_presets=uac::get_user_presets($config, {user=>$user, studio_id=>$params->{studio_id}});
my $request={
url => $ENV{QUERY_STRING}||'',
params => {
original => $params,
checked => $params
# checked => check_params($params),
},
};
$request = uac::prepare_request($request, $user_presets);
log::init($request);
#process header
my $headerParams = uac::set_template_permissions($request->{permissions}, $params);
$headerParams->{loc} = localization::get($config, {user=>$user, file=>'menu'});
template::process('print', template::check('default.html'), $headerParams);
#filter
my $lines = $cgi->param('lines');
$lines=100 if $lines eq '';
my $filter='' ;
$filter=' |grep -v "Use of uninitialized value in | grep -v redefined " ' if ($cgi->param('warn') eq '1');
#get file
my $file=$config->{system}->{log_file};
if ($cgi->param('log')eq'app'){
$file=$config->{system}->{log_debug_file};
}
if ($cgi->param('log')eq'mem'){
$file=$config->{system}->{log_debug_memory_file};
}
if ($cgi->param('log')eq'job'){
$file=$config->{system}->{job_log};
}
#output header
my $out='';
template::process('print','templates/error_log.html', $params);
#get log
my $cmd="tail -$lines ".$file.$filter;
print '<pre>'.$cmd.'</pre>';
my $log= `$cmd`;
$log=join("\n",reverse(split("\n",$log)));
#replace
if ($cgi->param('log')eq'app'){
$log=~s/\\n/<br>/gi;
}else{
$log=~s/</\&lt;/gi;
$log=~s/\\n/<\/pre><pre>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/gi;
}
#output content
print $log;

View File

@@ -0,0 +1,946 @@
#! /usr/bin/perl -w
use warnings "all";
use strict;
use URI::Escape;
use Encode;
use Data::Dumper;
use MIME::Base64;
use Encode::Locale;
use params;
use config;
use log;
use template;
use db;
use auth;
use uac;
#use roles;
use time;
use markup;
use project;
use studios;
use events;
use series;
use series_dates;
use series_events;
use user_stats;
use localization;
use eventOps;
binmode STDOUT, ":utf8";
my $r=shift;
(my $cgi, my $params, my $error)=params::get($r);
my $config = config::get('../config/config.cgi');
my $debug = $config->{system}->{debug};
my ($user,$expires) = auth::get_user($cgi, $config);
return if ((!defined $user) || ($user eq ''));
my $user_presets=uac::get_user_presets($config, {
user => $user,
project_id => $params->{project_id},
studio_id => $params->{studio_id}
});
$params->{default_studio_id}=$user_presets->{studio_id};
$params->{studio_id}=$params->{default_studio_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
$params->{project_id}=$user_presets->{project_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
my $request={
url => $ENV{QUERY_STRING}||'',
params => {
original => $params,
checked => check_params($params),
},
};
#print STDERR Dumper($request)."\n";
#set user at params->presets->user
$request = uac::prepare_request($request, $user_presets);
log::init($request);
$params=$request->{params}->{checked};
#show header
unless(params::isJson()){
my $headerParams=uac::set_template_permissions($request->{permissions}, $params);
$headerParams->{loc} = localization::get($config, {user=>$user, file=>'menu'});
template::process('print', template::check('default.html'), $headerParams);
}
return unless defined uac::check($config, $params, $user_presets);
print q{
<script src="js/datetime.js" type="text/javascript"></script>
<script src="js/event.js" type="text/javascript"></script>
<link rel="stylesheet" href="css/event.css" type="text/css" />
}unless(params::isJson);
if (defined $params->{action}){
if (
($params->{action} eq 'show_new_event')
|| ($params->{action} eq 'show_new_event_from_schedule')
){
show_new_event($config, $request);
return;
};
if (
($params->{action} eq 'create_event')
|| ($params->{action} eq 'create_event_from_schedule')
){
$params->{event_id}=create_event($config, $request);
unless(defined $params->{event_id}){
uac::print_error("failed");
return;
};
};
if ($params->{action} eq 'get_json') {
getJson($config, $request);
return;
}
if ($params->{action} eq 'delete') {delete_event($config, $request)};
if ($params->{action} eq 'save') {save_event( $config, $request)};
if ($params->{action} eq 'download') {download( $config, $request)};
}
$config->{access}->{write}=0;
show_event($config, $request);
#show existing event for edit
sub show_event{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
for my $attr ('project_id','studio_id', 'series_id', 'event_id'){
unless (defined $params->{$attr}){
uac::print_error("missing ".$attr." to show event");
return;
}
}
my $result=series_events::check_permission(
$request, {
permission => 'update_event_of_series,update_event_of_others',
check_for => ['studio','user','series','events'],
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
event_id => $params->{event_id}
}
);
unless($result eq '1'){
uac::print_error($result);
return undef;
}
$permissions->{update_event}=1;
print STDERR "check series permission ok\n";
#TODO: move to JS
my @durations=();
for my $duration (@{time::get_durations()}){
my $entry= {
name => sprintf("%02d:%02d", $duration/60, $duration %60),
value => $duration
};
push @durations, $entry;
}
my $event=series::get_event($config, {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
event_id => $params->{event_id}
});
unless (defined $event){
uac::print_error("event not found");
}
my $editLock=1;
if ((defined $permissions->{update_event_after_week}) && ($permissions->{update_event_after_week} eq '1')){
$editLock=0;
}else{
$editLock=0 if (series::is_event_older_than_days(
$config, {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
event_id => $params->{event_id},
max_age => 14
}
)==0);
}
# for rerun, deprecated
if(defined $params->{source_event_id}){
my $event2=series::get_event($config, {
allow_any => 1,
#project_id => $params->{project_id},
#studio_id => $params->{studio_id},
#series_id => $params->{series_id},
event_id => $params->{source_event_id}
});
if (defined $event2){
for my $attr ('title', 'user_title', 'excerpt', 'user_excerpt', 'content', 'topic', 'image', 'live no_event_sync', 'podcast_url', 'archive_url'){
$event->{$attr}=$event2->{$attr};
}
$event->{recurrence}=eventOps::getRecurrenceBaseId($event2);
$event->{rerun}=1;
}
}
$event->{rerun}=1 if ($event->{rerun}=~/a-z/);
$event->{series_id}=$params->{series_id};
$event->{duration}=events::get_duration($config, $event);
$event->{durations}=\@durations;
if (defined $event->{duration}){
for my $duration (@{$event->{durations}}){
$duration->{selected}=1 if ($event->{duration}eq $duration->{value});
}
}
$event->{start}=~s/(\d\d:\d\d)\:\d\d/$1/;
$event->{end}=~s/(\d\d:\d\d)\:\d\d/$1/;
# overwrite event with old one
#my $series_events=get_series_events($config,{
# project_id => $params->{project_id},
# studio_id => $params->{studio_id},
# series_id => $params->{series_id}
#});
#my @series_events=();
#for my $series_event (@$series_events){
# push @series_events, $series_event if ($series_event->{start} lt $event->{start});
#}
#$params->{series_events}=\@series_events;
# get all series
#my $series=series::get(
# $config,{
# project_id => $params->{project_id},
# studio_id => $params->{studio_id},
# }
#);
#for my $serie (@$series){
# $serie->{selected}=1 if $params->{series_id}==$serie->{series_id};
#}
#$params->{series}=$series;
# get event series
my $series=series::get(
$config,{
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id}
}
);
if(@$series==1){
$event->{has_single_events}=$series->[0]->{has_single_events};
}
#$event->{rerun}=1 if ((defined $event->{rerun})&&($event->{rerun}ne'0')&&($event->{rerun}ne''));
my $users=series::get_users(
$config,{
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id}
}
);
$params->{series_users}=$users;
#print STDERR Dumper($users);
$params->{series_users_email_list}=join(',', (map {$_->{email}} (@$users)) );
$params->{series_user_names}=join(' und ', (map { (split(/\s+/,$_->{full_name}))[0] } (@$users)) );
for my $permission (sort keys %{$permissions}){
$params->{'allow'}->{$permission}=$permissions->{$permission};
}
for my $key (keys %$event){
$params->{$key}=$event->{$key};
}
$params->{event_edited}=1 if (($params->{action} eq 'save')&&(! (defined $params->{error})));
$params->{event_edited}=1 if ( $params->{action} eq 'delete');
$params->{event_edited}=1 if (($params->{action} eq 'create_event')&&(! (defined $params->{error})));
$params->{event_edited}=1 if (($params->{action} eq 'create_event_from_schedule')&&(! (defined $params->{error})));
$params->{user}=$params->{presets}->{user};
# remove all edit permissions if event is over for more than 2 weeks
if ($editLock==1){
for my $key (keys %$params){
unless ($key=~/create_download/){
delete $params->{allow}->{$key} if $key=~/^(update|delete|create|assign)/;
}
}
$params->{edit_lock}=1;
}
#print STDERR Dumper($params);
$params->{loc} = localization::get($config, {user=>$params->{presets}->{user}, file=>'event'});
template::process('print', template::check('edit_event'), $params);
}
sub getJson{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
for my $attr ('project_id','studio_id', 'series_id', 'event_id'){
unless (defined $params->{$attr}){
uac::print_error("missing ".$attr." to show event");
return;
}
}
my $result=series_events::check_permission(
$request, {
permission => 'update_event_of_series,update_event_of_others',
check_for => ['studio','user','series','events'],
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
event_id => $params->{event_id}
}
);
unless($result eq '1'){
uac::print_error($result);
return undef;
}
$permissions->{update_event}=1;
my $event=series::get_event($config, {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
event_id => $params->{event_id}
});
unless (defined $event){
uac::print_error("event not found");
}
$event->{rerun}=1 if ($event->{rerun}=~/a-z/);
$event->{series_id}=$params->{series_id};
$event->{start}=~s/(\d\d:\d\d)\:\d\d/$1/;
$event->{end}=~s/(\d\d:\d\d)\:\d\d/$1/;
# get event series
my $series=series::get(
$config,{
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id}
}
);
if(@$series==1){
my $serie=$series->[0];
$event->{has_single_events}=$serie->{has_single_events};
if ($event->{has_single_events}eq'1'){
$event->{has_single_events}=1;
$event->{series_name}=undef;
$event->{episode}=undef;
}
}
$event->{duration}=events::get_duration($config, $event);
# for rerun
if ($params->{get_rerun}==1){
$event->{rerun}=1;
$event->{recurrence}=eventOps::getRecurrenceBaseId($event);
#$event=events::calc_dates($config, $event);
}
#print to_json($event);
template::process('print', 'json-p', $event);
}
#show new event from schedule
sub show_new_event{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
if($params->{action}eq'show_new_event'){
$params->{show_new_event}=1;
unless ($permissions->{create_event}==1){
uac::permissions_denied('create_event');
return;
}
}elsif($params->{action}eq'show_new_event_from_schedule'){
$params->{show_new_event_from_schedule}=1;
unless ($permissions->{create_event_from_schedule}==1){
uac::permissions_denied('create_event_from_schedule');
return;
}
}else{
uac::print_error("invalid action");
return 1;
}
# check for missing parameters
my $required_fields=['project_id', 'studio_id', 'series_id'];
push @$required_fields, 'start_date' if ($params->{action}eq'show_new_event_from_schedule');
my $event={};
for my $attr (@$required_fields){
unless (defined $params->{$attr}){
uac::print_error("missing ".$attr);
return;
}
$event->{$attr}=$params->{$attr};
}
my $serie=eventOps::setAttributesFromSeriesTemplate($config, $params, $event);
if($params->{action}eq'show_new_event_from_schedule'){
eventOps::setAttributesFromSchedule($config, $params, $event);
}else{
eventOps::setAttributesForCurrentTime($serie, $event);
}
if(defined $params->{source_event_id}){
#overwrite by existing event (rerun)
eventOps::setAttributesFromOtherEvent($config, $params, $event);
}
$event=events::calc_dates($config, $event);
if($serie->{has_single_events}eq'1'){
$event->{has_single_events}=1;
$event->{series_name}=undef;
$event->{episode}=undef;
}
#get next episode
$event->{episode}=series::get_next_episode(
$config, {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
}
);
delete $event->{episode} if $event->{episode}==0;
$event->{disable_event_sync}=1;
$event->{published}=1;
$event->{new_event}=1;
#copy event to template params
for my $key (keys %$event){
$params->{$key}=$event->{$key};
}
#add duration selectbox
#TODO: move to javascript
my @durations=();
for my $duration (@{time::get_durations()}){
my $entry= {
name => sprintf("%02d:%02d",$duration/60, $duration %60),
value => $duration
};
push @durations, $entry;
}
$params->{durations}=\@durations;
#set duration preset
for my $duration (@{$params->{durations}}){
$duration->{selected}=1 if ($event->{duration} eq $duration->{value});
}
#check user permissions and then:
$permissions->{update_event}=1;
#set permissions to template
for my $permission (keys %{$request->{permissions}}){
$params->{'allow'}->{$permission}=$request->{permissions}->{$permission};
}
$params->{loc} = localization::get($config, {user=>$params->{presets}->{user}, file=>'event,comment'});
template::process('print', template::check('edit_event'), $params);
#print '<pre>'.Dumper($params).'</pre>';
}
sub delete_event{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
my $event={};
for my $attr ('project_id', 'studio_id', 'series_id', 'event_id'){
unless (defined $params->{$attr}){
uac::print_error("missing ".$attr);
return;
}
$event->{$attr}=$params->{$attr};
}
my $result=series_events::check_permission(
$request, {
permission => 'delete_event',
check_for => ['studio','user','series','events','event_age'],
project_id => $params->{project_id},
studio_id => $event->{studio_id},
series_id => $event->{series_id},
event_id => $event->{event_id}
}
);
unless($result eq '1'){
uac::print_error($result);
return undef;
}
$config->{access}->{write}=1;
#set user to be added to history
$event->{user}=$params->{presets}->{user};
$result=series_events::delete_event($config, $event);
unless (defined $result){
uac::print_error('could not delete event');
return undef;
}
user_stats::increase($config, 'delete_events', {
project_id => $event->{project_id},
studio_id => $event->{studio_id},
series_id => $event->{series_id},
user => $event->{user}
});
uac::print_info("event deleted");
}
#save existing event
sub save_event{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
for my $attr ('project_id','studio_id', 'series_id', 'event_id'){
unless (defined $params->{$attr}){
uac::print_error("missing ".$attr." to show event");
return;
}
}
#print Dumper($params);
my $start = $params->{start_date},
my $end = time::add_minutes_to_datetime($params->{start_date}, $params->{duration});
#check permissions
my $options={
permission => 'update_event_of_series,update_event_of_others',
check_for => ['studio','user','series','events','studio_timeslots','event_age'],
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
event_id => $params->{event_id},
start => $start,
end => $end,
};
my $result=series_events::check_permission(
$request, $options
);
unless($result eq '1'){
uac::print_error($result);
return;
}
#changed columns depending on permissions
my $entry={
id => $params->{event_id}
};
my $found=0;
#content fields
for my $key ('content','topic','title','excerpt','episode','image','podcast_url','archive_url'){
next unless defined $permissions->{'update_event_field_'.$key};
if ($permissions->{'update_event_field_'.$key} eq '1'){
$entry->{$key} = $params->{$key} if defined $params->{$key};
$found++;
}
}
#user extension fields
for my $key ('title','excerpt'){
next unless defined $permissions->{'update_event_field_'.$key.'_extension'};
if ($permissions->{'update_event_field_'.$key.'_extension'} eq '1'){
$entry->{'user_'.$key} = $params->{'user_'.$key} if defined $params->{'user_'.$key};
$found++;
}
}
#status field
for my $key ('live', 'published', 'playout', 'archived', 'rerun', 'disable_event_sync'){
next unless defined $permissions->{'update_event_status_'.$key};
if ($permissions->{'update_event_status_'.$key} eq '1'){
$entry->{$key} = $params->{$key}||0;
$found++;
}
}
$entry->{modified_by}=$params->{presets}->{user};
#get event from database (for history)
my $event=series::get_event($config, {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
event_id => $params->{event_id}
});
unless(defined $event){
uac::print_error("event not found");
return;
}
$config->{access}->{write}=1;
#update content
if ($found>0){
$entry=series_events::save_content($config,$entry);
for my $key (keys %$entry){
$event->{$key} = $entry->{$key};
}
}
#update time
if( (defined $permissions->{update_event_time}) && ($permissions->{update_event_time}eq'1') ){
my $entry={
id => $params->{event_id} ,
start_date => $params->{start_date} ,
duration => $params->{duration} ,
# end => $params->{end_date} ,
};
$entry=series_events::save_event_time($config, $entry) ;
for my $key (keys %$entry){
$event->{$key} = $entry->{$key};
}
}
$event->{project_id} = $params->{project_id};
$event->{studio_id} = $params->{studio_id};
$event->{series_id} = $params->{series_id};
$event->{event_id} = $params->{event_id};
$event->{user} = $params->{presets}->{user};
#update recurrences
series::update_recurring_events($config, $event);
#update history
event_history::insert($config, $event);
user_stats::increase($config, 'update_events', {
project_id => $event->{project_id},
studio_id => $event->{studio_id},
series_id => $event->{series_id},
user => $event->{user}
});
#print "error" unless (defined $result);
$config->{access}->{write}=0;
uac::print_info("event saved");
}
sub create_event{
my $config=shift;
my $request=shift;
my $params = $request->{params}->{checked};
my $permissions = $request->{permissions};
my $checklist=['studio','user','create_events','studio_timeslots'];
if ($params->{action} eq 'create_event_from_schedule'){
push @$checklist, 'schedule' if $params->{action} eq 'create_event_from_schedule';
}
my $start = $params->{start_date},
my $end = time::add_minutes_to_datetime($params->{start_date}, $params->{duration});
my $result=series_events::check_permission(
$request, {
permission => 'create_event,create_event_of_series',
check_for => $checklist,
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
start_date => $params->{start_date},
start => $start,
end => $end
}
);
#print Dumper(" start_date => $params->{start_date}");
unless($result eq '1'){
uac::print_error($result);
return undef;
}
#get series name from series
my $series=series::get(
$config,{
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
}
);
if(@$series!=1){
uac::print_error("series not found");
return undef;
}
my $serie=$series->[0];
#get studio location from studios
my $studios=studios::get($config, {
project_id => $params->{project_id},
studio_id => $params->{studio_id}
});
unless(defined $studios){
uac::print_error("studio not found");
return undef;
}
unless(@$studios==1){
uac::print_error("studio not found");
return undef;
}
my $studio=$studios->[0];
$config->{access}->{write}=1;
#insert event content and save history
my $event_id=series_events::insert_event(
$config,{
project_id => $params->{project_id},
studio => $studio,
serie => $serie,
event => $params,
user => $params->{presets}->{user}
}
);
uac::print_error("could not insert event") if $event_id <= 0;
#assign event to series
$result=series::assign_event(
$config, {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
event_id => $event_id
}
);
uac::print_error("could not assign event") unless defined $result;
#update recurrences
my $event=$params;
$event->{event_id}=$event_id;
series::update_recurring_events($config, $event);
# update user stats
user_stats::increase($config, 'create_events', {
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
user => $params->{presets}->{user}
});
#forward to edit event
#print STDERR Dumper($event_id);
#$params->{event_id}=$event_id;
uac::print_info("event created");
return $event_id;
}
#TODO: replace permission check with download
sub download{
my $config =shift;
my $request=shift;
my $params =$request->{params}->{checked};
my $permissions=$request->{permissions};
my $result=series_events::check_permission(
$request, {
permission => 'update_event_of_series,update_event_of_others',
check_for => ['studio','user','series','events'],
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
event_id => $params->{event_id}
}
);
unless($result eq '1'){
uac::print_error($result);
return undef;
}
$permissions->{update_event}=1;
my $request2={
params=>{
checked=>events::check_params($config,
{
event_id => $params->{event_id},
template => 'no',
limit => 1,
}
)
},
config => $request->{config},
permissions => $request->{permissions}
};
$request2->{params}->{checked}->{published}='all';
my $events=events::get($config, $request2);
my $event=$events->[0];
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 "event.cgi::download no valid datetime found $datetime\n";
return;
}
my $archive_dir=$config->{locations}->{local_archive_dir};
my $archive_url=$config->{locations}->{local_archive_url};
print STDERR "archive_dir: ".$archive_dir."\n";
print STDERR "archive_url: ".$archive_url."\n";
print STDERR "event.cgi::download look for : $archive_dir/$datetime*.mp3\n";
my @files=glob($archive_dir.'/'.$datetime.'*.mp3');
#print STDERR Dumper(\@files);
if (@files>0){
my $file=$files[0];
my $key=int(rand(99999999999999999));
$key= encode_base64($key);
$key=~s/[^a-zA-Z0-9]//g;
#decode filename
$file = Encode::decode("UTF-8", $file);
my $cmd="ln -s '".$file."' '".$archive_dir.'/'.$key.".mp3'";
my $url=$archive_url.'/'.$key.'.mp3';
#print $cmd."\n";
print `$cmd`;
$request->{params}->{checked}->{download}=
"Hallo,\n\n".
"anbei der Mitschnitt fuer\n"
.$event->{start_date_name}.", ".$event->{start_time_name}." - ".$event->{series_name}.' - '.$event->{title}.":\n"
.$url."\n"
."\nDer Link wird nach 7 Tagen geloescht. (bitte nicht weitergeben)\n"
."Gruss, Peter\n"
;
}
}
sub check_params{
my $params=shift;
my $checked={};
my $template='';
$checked->{template}=template::check($params->{template},'series');
my $debug=$params->{debug} || '';
if ($debug=~/([a-z\_\,]+)/){
$debug=$1;
}
$checked->{debug}=$debug;
#numeric values
for my $param ('id', 'project_id', 'studio_id', 'default_studio_id', 'user_id', 'series_id', 'event_id', 'source_event_id', 'episode'){
if ((defined $params->{$param})&&($params->{$param}=~/^\d+$/)){
$checked->{$param}=$params->{$param};
}
}
if (defined $checked->{studio_id}){
$checked->{default_studio_id}=$checked->{studio_id};
}else{
$checked->{studio_id}=-1;
}
#scalars
for my $param ('studio', 'search', 'from', 'till', 'hide_series'){
if (defined $params->{$param}){
$checked->{$param}=$params->{$param};
$checked->{$param}=~s/^\s+//g;
$checked->{$param}=~s/\s+$//g;
}
}
#numbers
for my $param ('duration', 'recurrence'){
if ((defined $params->{$param})&&($params->{$param}=~/(\d+)/)){
$checked->{$param}=$1;
}
}
#checkboxes
for my $param ('live', 'published', 'playout', 'archived', 'rerun', 'disable_event_sync','get_rerun'){
if ((defined $params->{$param})&&($params->{$param}=~/([01])/)){
$checked->{$param}=$1;
}
}
#strings
for my $param (
'series_name', 'title', 'excerpt', 'content', 'topic', 'program', 'category', 'image', 'user_content',
'user_title', 'user_excerpt', 'podcast_url', 'archive_url'
){
if (defined $params->{$param}){
#$checked->{$param}=uri_unescape();
$checked->{$param}=$params->{$param};
$checked->{$param}=~s/^\s+//g;
$checked->{$param}=~s/\s+$//g;
}
}
#dates
for my $param ('start_date','end_date'){
if((defined $params->{$param})&&($params->{$param}=~/(\d\d\d\d\-\d\d\-\d\d \d\d\:\d\d)/)){
$checked->{$param}=$1.':00';
}
}
#actions and roles
$checked->{action}='';
if (defined $params->{action}){
if ($params->{action}=~/^(save|delete|download|show_new_event|show_new_event_from_schedule|create_event|create_event_from_schedule|get_json)$/){
$checked->{action}=$params->{action};
}
}
#print STDERR Dumper($checked);
return $checked;
}
__DATA__
#requires studio_id,series_id,location
sub get_series_events{
my $config=shift;
my $options=shift;
return undef unless defined $options->{project_id};
return undef unless defined $options->{studio_id};
return undef unless defined $options->{series_id};
$options->{template}= 'no'; # deprecated
$options->{limit} = 200; # deprecated
$options->{get} = 'no_content'; # deprecated
$options->{archive} = 'all'; # deprecated
my $events=series::get_events($config, $options);
return $events;
}

View File

@@ -0,0 +1,232 @@
#! /usr/bin/perl -w
use warnings "all";
use strict;
use URI::Escape;
use Encode;
use Data::Dumper;
use MIME::Base64;
#use Text::Diff ();
use Text::Diff::FormattedHTML;
use params;
use config;
use log;
use template;
use db;
use auth;
use uac;
#use roles;
use time;
use markup;
use studios;
use event_history;
use events;
#use series;
#use series_dates;
use series_events;
use localization;
binmode STDOUT, ":utf8";
my $r=shift;
(my $cgi, my $params, my $error)=params::get($r);
my $config = config::get('../config/config.cgi');
my $debug = $config->{system}->{debug};
my ($user,$expires) = auth::get_user($cgi, $config);
return if ((!defined $user) || ($user eq ''));
my $user_presets=uac::get_user_presets($config, {user=>$user, studio_id=>$params->{studio_id}});
$params->{default_studio_id}=$user_presets->{studio_id};
$params->{studio_id}=$params->{default_studio_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
my $request={
url => $ENV{QUERY_STRING}||'',
params => {
original => $params,
checked => check_params($params),
},
};
#print STDERR Dumper($request)."\n";
#set user at params->presets->user
$request = uac::prepare_request($request, $user_presets);
log::init($request);
$params=$request->{params}->{checked};
#show header
my $headerParams=uac::set_template_permissions($request->{permissions}, $params);
$headerParams->{loc} = localization::get($config, {user=>$user, file=>'menu'});
template::process('print', template::check('default.html'), $headerParams);
return unless uac::check($config, $params, $user_presets)==1;
print q{
<script src="js/datetime.js" type="text/javascript"></script>
<script src="js/event.js" type="text/javascript"></script>
<link rel="stylesheet" href="css/event.css" type="text/css" />
};
$config->{access}->{write}=0;
if($params->{action} eq'diff'){
compare($config, $request);
return;
}
show_history($config, $request);
#show existing event history
sub show_history{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
for my $attr ('studio_id'){ # 'series_id','event_id'
unless (defined $params->{$attr}){
uac::print_error("missing ".$attr." to show changes");
return;
}
}
unless($permissions->{read_event}==1){
uac::print_error("missing permissions to show changes");
return;
}
my $options={
project_id => $params->{project_id},
studio_id => $params->{studio_id},
limit => 200
};
$options->{series_id} = $params->{series_id} if defined $params->{series_id};
$options->{event_id} = $params->{event_id} if defined $params->{event_id};
my $events=event_history::get($config, $options);
#print STDERR Dumper($events);
return unless defined $events;
$params->{events}=$events;
for my $permission (keys %{$permissions}){
$params->{'allow'}->{$permission}=$request->{permissions}->{$permission};
}
#print STDERR Dumper($params);
$params->{loc} = localization::get($config, {user=>$params->{presets}->{user}, file=>'event_history'});
template::process('print', template::check('event_history'), $params);
}
#show existing event history
sub compare{
my $config=shift;
my $request=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
for my $attr ('project_id','studio_id','event_id','v1','v2'){
unless (defined $params->{$attr}){
uac::print_error("missing ".$attr." to show changes");
return;
}
}
unless($permissions->{read_event}==1){
uac::print_error("missing permissions to show changes");
return;
}
print qq{<link href="css/diff.css" rel="stylesheet">}."\n";
if ($params->{v1} > $params->{v2}){
my $t = $params->{v1};
$params->{v1} = $params->{v2};
$params->{v2} = $t;
}
my $options={
project_id => $params->{project_id},
studio_id => $params->{studio_id},
series_id => $params->{series_id},
event_id => $params->{event_id},
change_id => $params->{v1},
limit => 2
};
my $events=event_history::get($config, $options);
return unless @$events==1;
my $v1=$events->[0];
$options->{change_id}=$params->{v2};
$events=event_history::get($config, $options);
return unless @$events==1;
my $v2=$events->[0];
my $t1=eventToText($v1);
my $t2=eventToText($v2);
if($t1 eq $t2){
print "no changes\n";
return;
}
#print "<style>".diff_css."</style>";
#print '<pre>';
#my $diff=diff_strings( { vertical => 1 }, $t1, $t2);
my $diff=diff_strings( { }, $t1, $t2);
#print Text::Diff::diff(\$t1, \$t2, { STYLE => "Table" });
#print Text::Diff::diff($v1, $v2, { STYLE => "Table" });
print $diff;
#print '</pre>';
}
sub eventToText{
my $event=shift;
my $s=events::get_keys($event)->{full_title}."\n";
$s.=$event->{excerpt}."\n";
$s.=$event->{user_excerpt}."\n";
$s.=$event->{topic}."\n";
$s.=$event->{content}."\n";
#print STDERR "DUMP\n$s";
return $s;
}
sub check_params{
my $params=shift;
my $checked={};
my $template='';
$checked->{template}=template::check($params->{template},'event_history');
my $debug=$params->{debug} || '';
if ($debug=~/([a-z\_\,]+)/){
$debug=$1;
}
$checked->{debug}=$debug;
#numeric values
for my $param ('id', 'project_id', 'studio_id', 'default_studio_id', 'user_id', 'series_id', 'event_id', 'v1', 'v2'){
if ((defined $params->{$param})&&($params->{$param}=~/^\d+$/)){
$checked->{$param}=$params->{$param};
}
}
if (defined $checked->{studio_id}){
$checked->{default_studio_id}=$checked->{studio_id};
}else{
$checked->{studio_id}=-1;
}
#actions and roles
$checked->{action}='';
if (defined $params->{action}){
if ($params->{action}=~/^(show|diff)$/){
$checked->{action}=$params->{action};
}
}
#print STDERR Dumper($checked);
return $checked;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,641 @@
# !/usr/bin/perl -w
use warnings "all";
use strict;
use Data::Dumper;
use params;
use config;
use log;
use template;
use auth;
use uac;
use roles;
use studios;
use markup;
use URI::Escape;
use Encode;
use localization;
#binmode STDOUT, ":utf8";
my $r=shift;
(my $cgi, my $params, my $error)=params::get($r);
my $config = config::get('../config/config.cgi');
my $debug = $config->{system}->{debug};
my ($user,$expires) = auth::get_user($cgi, $config);
return if ((!defined $user) || ($user eq ''));
my $user_presets=uac::get_user_presets($config, {
user => $user,
project_id => $params->{project_id},
studio_id => $params->{studio_id}
});
$params->{default_studio_id}=$user_presets->{studio_id};
$params->{studio_id}=$params->{default_studio_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
$params->{project_id}=$user_presets->{project_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
my $request={
url => $ENV{QUERY_STRING}||'',
params => {
original => $params,
checked => check_params($params),
},
};
$request = uac::prepare_request($request, $user_presets);
log::init($request);
$params=$request->{params}->{checked};
#process header
my $headerParams=uac::set_template_permissions($request->{permissions}, $params);
$headerParams->{loc} = localization::get($config, {user=>$user, file=>'menu'});
template::process('print', template::check('default.html'), $headerParams);
return unless uac::check($config, $params, $user_presets)==1;
my $toc=$headerParams->{loc}->{toc};
print q!
<style>
#content h1{
font-size:1.6em;
}
#content h2{
font-size:1.2em;
padding-top:1em;
padding-left:2em;
}
#content h3{
font-size:1em;
padding-left:4em;
}
#content h4{
font-size:1em;
padding-left:4em;
}
#content p{
padding-left:6em;
line-height:1.5em;
}
#content ul{
padding-left:7em;
}
#content li{
line-height:1.5em;
}
body #content{
max-width:60em;
}
</style>
<script>
function addToToc(selector){
$(selector).each(function(){
if($(this).hasClass('hide'))return
var title=$(this).text();
var tag=$(this).prop('tagName');
var span=2;
if(tag=='H2')span=4;
if(tag=='H3')span=6;
if(tag=='H4')span=8;
var url=title;
url=url.replace(/[^a-zA-Z]/g,'-')
url=url.replace(/\-+/g, '-')
$(this).append('<a name="'+url+'" />');
$('#toc').append('<li style="margin-left:'+span+'em"><a href="#'+url+'">'+title+'</a></li>')
});
}
$( document ).ready(function() {
addToToc('#content h1,#content h2,#content h3,#content h4');
})
</script>
!;
print markup::creole_to_html(getHelp($headerParams->{loc}->{region}));
sub getHelp{
my $region=shift;
return getGermanHelp() if $region eq 'de';
return getEnglishHelp();
}
sub getGermanHelp{
return q{
<div id="toc"><h1 class="hide">Inhaltsverzeichnis</h1></div>
= Menü
== Login
Für das Login ist ein persönliches Konto für jeden Nutzer mit einem Passwort notwendig.
Persönliche Logins dürfen nicht weitergegeben werden, es können eigene Konten mit persönlichen Einstellungen für jeden Nutzer verwendet werden.
Am Ende einer Sitzung bitte ausloggen.
== Einstellungen
Hier können folgende persönliche Einstellungen vorgenomment werden:
* Auswahl der Sprache der Oberfläche (momentan Deutsch und Englisch)
* Auswahl der Farben für Sendungen, Plantermine, Konflikte, etc.
* Auswahl der Voreinstellungen für den Kalender
* Ändern des Passworts
== Projekte und Studios
Alle Sendereihen, Termine, Rechte und Einstellungen werden immer abhängig vom ausgewählen Projekt und Studio angezeigt.
Ein Projekt kann mehrere voneinander unabhängige Studios beinhalten.
Das Projekt und das Studio kann oben rechts ausgewählt werden.
Abhängig von seinen Rechten kann ein Nutzer in verschiedenen Projekten und Studios unterschiedliche Aktionen durchführen.
== Rechte
Einzelnen Nutzern können verschiedene Rollen im aktuellen Studio zugewiesen werden (z.B. Gast, Redaktion, Programmplanung, Studio Manager).
Es ist möglich eigene Rollen zu definieren und an Nutzer zu vergeben.
Jeder Nutzer sollte nur die Rechte zugewiesen bekommen, die er wirklich benötigt.
Dies vereinfacht die Benutzung, da Nutzer nur die für ihn wichtigen Punkte sehen und Fehlbedienungen ausgeschlossen werden können, z.B. versehentliches Löschen einer fremden Sendung.
Die Zuweisung von Rollen zu Nutzern ermöglicht ein verteiltes Arbeiten, z.B. jemand kümmert sich um die Sendeplanung und das Anlegen von Sendungen, Redaktionen können eigenständig Inhalte ihrer Sendungen bearbeiten.
Die zugewiesenen Rechte gelten immer nur für das gewählte Projekt und Studio. Die einzelnen Studios bestimmen selbständig, wer welche Rechte in ihrem Studio hat.
== Nutzer
Es können individuelle Benutzerkonten angelegt und bearbeitet werden.
Hier lässt sich die email-Addresse bearbeiten, ein Nutzer sperren oder löschen.
Die Berechtigungen des Nutzers können über ihm zugewiesene Rollen definiert werden.
== Sendezeiten
Hier können für ein Projekt und die Sendezeiten für mehrere Studios eingetragen werden.
Sendungen eines Studios lassen sich nur innerhalb der Sendezeiten des Studios anlegen.
Sendezeiten bestehen aus
* Datum und Zeit des Beginns des ersten Sendeblocks,
* Datum und Zeit des Endes des ersten Sendeblocks,
* in welchem Interval der Sendeblock stattfindet (täglich, wöchentlich, ...)
* dem geplanten Enddatum des Sendeblocks
* dem Studio, dass im Sendeblock sendet.
Komplexe Sendezeiten lassen sich über mehrere Definitionen definieren.
== Kalender
Der Kalender zeigt alle Sendungen und die Plantermine seiner Sendereihen an.
Links oben lässt sich der angezeigte Zeitraum auswählen.
Zeiten, in denen Termine für ein Studio angelegt werden können, werden gestrichelt angezeigt.
Für Termine wird der Status (live, vorproduziert, archiviert,...) in Form von Icons angezeigt.
Über die Suche kann eine Liste von Sendungen angezeigt werden, die den Suchtext enthalten.
Über Filter lassen sich Konflikte und Sendungen mit einem bestimmten Status farblich hervorheben.
Mögliche Ursachen für Konflikte:
* mehrere Sendungen zur selben Zeit
* mehrere Planermine zur selben Zeit
* eine Sendung und ein Plantermin einer anderen Sendereihe zur selben Zeit
* eine Sendung ist nicht mit einem Plantermin verknüpft
== Sendereihen
Der Menüpunkt "Sendereihe" zeigt eine Übersicht aller Sendereihen eines Studios an.
Sendereihen, die lange nicht gesendet wurden, können über "alte Sendungen" eingeblendet werden.
Eine Sendereihe umfasst
* eine Vorlage für das Anlegen neuer Sendungen,
* die Verwaltung von Planterminen
* die Mitglieder der Redaktion der Sendereihe.
Alle Redaktionsmitglieder einer Sendereihe können die Sendungen einer Sendereihe bearbeiten.
== Plantermine
Plantermine ermöglichen eine vorausschauende Planung ohne dass alle Sendungen einer Sendereihe separat angelegt werden müssen.
Bei Änderungen der Planung können alle Plantermine in einem einzelnen Schritt angelegt, verschoben oder gelöscht werden.
Plantermine können einzelne Termine oder sich wiederholende Termine sein, die innerhalb der Studio-Zeiten liegen müssen.
Plantermine werden im Kalender angezeigt, können aber erst bearbeitet oder veröffentlicht werden, wenn für sie eine Sendung angelegt wurde.
Sendungen sollten erst angelegt werden, wenn der Plantermin bestätigt wurde.
Sobald eine Sendung angelegt wurde, existiert sie unabhängig vom Plantermin. Eine nachträgliche Änderung der Plantermine hat keine Auswirkungen auf schon bestätigte und angelegte Sendungen.
= Aktionen
== Sendungen planen
Unter "Sendereihen" können Plantermine für eine ausgewählte Sendereihe eingetragen werden.
Plantermin anlegen:
* im Kalender beim Klick auf den gewünschten freien Zeitbereich innerhalb der Sendezeiten.
* Unter "Sendereihe" / "Planung" in der Liste der Plantermine
Plantermin löschen:
* im Kalender beim Klick mit der rechten Maustaste auf einen Plantermin.
* im Kalender beim Klick auf einen Plantermin, dann unter "Planungstermin löschen"
* Unter "Sendereihe" / "Planung" in der Luste der Plantermine
== Arten von Planterminen
==== 1. Einzeltermin
**Start**: das Datum und die Zeit des Termin.
**Dauer** : Anzahl in Minuten
==== 2. Wiederholungstermine mit fester Periode
**Start** : ein festes Datum und eine Zeit
**Dauer** : in Minuten
**wiederholt bis**: bis zu welchem Datum Plantermine erstellt werden sollen
**wie oft**: alle wieviel Tage oder Wochen die Sendung wiederholt wird
Beispiel: alle 2 Wochen
==== 3. Wiederholungstermine auf Basis der Woche im Monat
**Start** : ein festes Datum und eine Zeit
**Dauer** : in Minuten
**wiederholt bis**: bis zu welchem Datum Plantermine erstellt werden sollen
**Woche** : die wievielte Woche im Monat
**Wochentag**: welcher Wochentag
**wie oft**: jedes Mal, jedes 2te Mal,... Die Wiedeholung beginnt mit dem ausgewählten Starttermin.
Beispiel: jeden 5.Montag im Monat, jedes 2te Mal
==== 4. Ausnahmen
Wenn bestimmte geplante Termine nicht stattfinden sollen, können separate Ausnahmetermine über das Häkchen "Ausnahme" angelegt werden.
Ausnahmetermine erscheinen
* nicht als Plantermin im Kalender und
* durchgestrichen in der Liste der geplanten Termine einer Sendereihe.
für Einzeltermine: der Plantermin kann einfach gelöscht werden.
für Wiederholungstermine: der ausfallende Plantermin kann als zusätzlicher Einzel-Planungstermin definiert werden.
Es ist auch möglich, wiederholende Ausnahmen zu definieren. Beispiel:
* ein Plantermin alle 2 Wochen und zusätzlich
* ein Ausnahmetermin alle 3 Wochen
== Sendereihe anlegen
im Menüpunkt "Sendereihe" unter "Sendereihe hinzugügen"
== Sendereihe bearbeiten
im Menüpunkt "Sendereihe" per Klick auf die Sendereihe
beim Bearbeiten einer Sendung per "Sendereihe bearbeiten"
== Sendung anlegen
Um eine Sendung anzulegen, muss ein Plantermin für die Sendereihe der Sendung existieren.
Im Kalender kann dazu ein freier Sendetermin mit der Maus gewählt werden und ein Plantermin angelegt werden.
Existiert der Plantermin, kann per Klick auf den Plantermin eine neue Sendung angelegt werden.
Beim Anlegen einer Sendung wird die Vorlage aus der Sendereihe in die Sendung kopiert.
Solbald die Sendung angelegt wurde, kann die Sendung von der Redaktion der Sendereihe bearbeitet werden.
Für nummerierte Sendungen wird die Nummer der Episode automatisch ermittelt, falls eine vorherige Sendung eine Episode eingetragen hat.
Ist der Titel der Sendung identisch zu einer existierenden, wird sie automatisch als Wiederholung gekennzeichnet.
== Sendung bearbeiten
Nachdem eine Sendung angelegt wurde, kann sie im Kalender oder in der Liste der Sendungen der Sendereihe bearbeitet werden.
=== Sendebeschreibung
Dies umfasst einzelne Felder für den Titel, den Auszug, aktuelle Themen, die Sendebeschreibung und ein Bild.
Für Titel und Auszug existieren separate Felder, die von der Redaktion bearbeitet werden können,
falls die Redaktion keine Rechte für die Bearbeitung der Felder Titel und Auszug besitzt.
=== Status
Von der Planung bis zur Archivierung kann der aktuelle Status einer Sendung über StatusFelder geändert werden.
Im Kalender kann nach dem Status gefiltert werden.
Folgende Status-Felder gibt es:
* **Live-Sendung**: die Sendung ist keine Vorproduktion
* **veröffentlicht**: die Sendung ist auf der Webseite sichtbar
* **im Playout**: die Vorproduktion ist ins Playout-System eingetragen
* **Wiederholung**: die Sendung ist eine Wiederholung
* **archiviert**: nach der Sendung wurde der Mittschnitt archiviert, z.B. auf CBA, FRN
* **kein Google Import**: der Inhalt der Sendung soll nicht durch einen Google-Import überschrieben werden
=== Aktionen beim Bearbeiten einer Sendung
* Sendereihe bearbeiten: Vorlage, Planung, Redaktion der Sendereihe ändern
* Sendungen zeigen: alle Sendungen der Sendereihe zeigen
* in andere Sendereihe verschieben: die Sendung wird von der ausgewählten Sendereihe abgekoppelt und in eine andere Sendereihe verschoben.
* Mittschnitt runterladen: Sobald ein Mittschnitt für die Sendung existiert (nach Ausstrahlung) wird ein temporärer Link zum Mittschnitt erzeugt (momentan nur Piradio).
* Wiederholung von alter Sendung: Der Inhalt der Sendebeschreibung wird von einer auswählbaren existierenden Sendung kopiert.
* Erinnerung: Eine Mail zur Erinnerung wird generiert und in einem externen Email-Programm anagezeigt.
* Änderungen: Eine Liste der Änderungen an dem Sendeeintrag
* Löschen: Die Sendung und ihre Beschreibung wird gelöscht
* Programmansicht: die Sendung wird im Programmplan angezeigt.
=== Bedingungen zum Bearbeiten einer Sendung
* Die Sendung muss einer Sendereihe zugeordnet sein.
* Die Sendung muss innerhalb der Sendezeiten des ausgewählten Projekts und Studios liegen.
* Der Benutzer muss der Redaktion der Sendereihe zugeordnet sein
* Der Benutzer benötigt Redaktionsrechte
};
}
sub getEnglishHelp{
return q{
<div id="toc"><h1 class="hide">Table of Contents</h1></div>
= Menu
== Login
To log in a account and a password is required for each user.
An account allows to set individual settings for each user.
Personal accounts should not be shared.
Please log out at end of each session.
== Settings
A user can customize following user settings:
* The language of the user interface (English, German)
* Colors for broadcasts, schedules, conflicts and more.
* default time range displayed at the calendar
* change the password
== Projects and Studios
All Series, Dates, Permissions and Settings are displayed depending on the selected project and studio.
A project consists of one or more studios.
Project and studio can be selected at the top right of each page.
A user can execute different actions depending on the permissions the user has for the selected project and studio.
== Permissions
A user can be assigned to different roles for a selected project and studio
(for example Guest, Editor, Program Scheduler, Studio Manager).
A role is a set of selected permissions.
It is possible to define new roles and assign them to selected users.
Each user should get only the permissions he or she really needs.
This eases using the system, due to a user only sees the actions that are assigned to the role.
It can prevent failures, for example deleting a broadcast the user is not assigned to.
By assigning roles to users the workflow can be done by multiple users with different roles.
For example one can schedule the program, while editors can fill in the content for their broadcasts.
Permissions of an user can be individually set for each project and studio.
== Users
At the menu Users you can edit the user accounts.
User accounts can be locked or deleted, one can edit the email address and assign roles to the user account.
== Time Slots
At the Time Slots menu you can assign time spans for each studio of the project.
One can create broadcasts only within the broadcast date ranges of the selected studio.
This prevents to create broadcasts out of the time slots defined.
Time Slot definition consists of
* start date and time of the first time slot,
* end date and time of the first time slot,
* The interval of the time slot (daily, weekly, and more)
* the end date of the last time slot
* the studio which broadcasts at the selected time slot.
You can define multiple time slots for each studio
== Calendar
The calendar shows all broadcasts and schedules of the series assigned to the selected project and studios.
You can select the displayed time range at the upper left.
Time slots of the studio are displayed dashed.
There are icons to show the status of each broadcast (live, preproduced, archived,...).
By using the search field one can find a list of broadcasts and schedules containing the search value.
There are filters to mark conflicts and status by different colors.
Possible conflicts:
* multiple broadcasts at the same time
* multiple schedules at the same time
* a broadcast at the same time as a schedule of another series.
* a broadcast is not assigned to a schedule or a series.
== Series
The series menu gives an overview of all series of the selected project and studio.
Series that have no broadcasts in the previous weeks can be displayed by "old series" button.
The series consist of
* a template for creating new broadcasts
* the series schedule
* the editors of the series
All editors of a series can edit the broadcasts of a series.
== Schedule
schedule dates allow to schedule broadcasts without separately creating single broadcasts for a series.
Schedule dates can be created, moved or deleted in a single step.
Schedule dates can be single dates or recurring dates. Both have to be inside the time slots of the project and studio.
Schedule dates are displayed in the calendar. One can create a broadcasts from an existing schedule date only. This should be done if the schedule date has been confirmed to avoid unneccessary editing of the date.
If a broadcast entry has been created it exists independent on the schedule date. If the schedule date is changed after creating a broadcast from the broadcast will not be changed.
= Actions
== schedule Broadcasts
At "Series" menu schedule dates can be edited for the selected series.
create schedule dates:
* at Calendar click on a free date of one of the displayed time slots. (Studio time slots are to be defined before.)
* at Series / Schedule one can edit the schedule
delete schedule dates:
* at Calendar right mouse clock on a schedule date.
* at Calendar select a schedule date, then select the remove schedule button.
* At Series / Schedule one can edit the schedule
== Types of schedule dates
==== 1. single date
**Start**: the date and time of the single schedule
**Duration** : in minutes
==== 2. Recurring Schedule with fix interval
**Start** : the start date and time of the first broadcast
**Duration** : in minutes
**End**: date of the last broadcast
**interval**: Interval of recurrence (daily, weekly, ...)
==== 3. Recurring Schedule based on week of month
**Start** : the start date and time of the first broadcast
**Duration** : in minutes
**End**: date of the last broadcast
**Week of Month** : from first to fifth week of month
**Weekday**: the weekday
**every nth time**: if not every date of the recurring schedule should be used, one can select to use the 5th Monday of a month, each other time.
==== 4. Exceptions
On having multiple recurring schedules one can use exceptions to define single or recurring dates a broadcast should not happen.
Exception schedule dates are
* not displayed in the calendar
* displayed striked through at the list of scheduled dates of a series.
Exceptions for single date : the schedule date will be deleted
Exceptions for recurring schedule dates: a single exception will be created for the date the broadcast will not take place at.
Additionally it is possible to create recurring exceptions.
Example 1: a schedule every two weeks and an exception schedule every three weeks
Example 2: a daily schedule for the whole year and an exception schedule from first until last of May.
== create series
At menu "Series" click "add Series" button
== edit Series
At menu "Series" select the series to edit
At editing a broadcast event, click on "edit series"
== create a broadcast event
To create a broadcast event a schedule has to be created for the series first.
At calendar choose a free time slot and create a schedule.
At calendar select the schedule date to create a new broadcast.
On creating broadcast Bthe template of the series will be copied to the broadcast.
Once the broadast has been created the entry can be edited by the editors of the broadcast.
The number of the episode will be increased automatically if "count episodes" has been selected at series template.
A broadcast event will be marked as recurring event if the title of the broadcast is the same as the title of an existing broadcast.
== edit a broadcast
Once a broadcast has been created, it can be edited by selecting at Calendar or at list of broadcasts at Series.
=== Broadcast description
There are fields for the title, the excerpt, current topice, a textual description and an image.
There are separate fields for title and excerpt that can be used to be edited by editors, in case editors have not the
permission to edit title and excerpt themself.
In general editing each field can be selected for each role of the permission sets.
=== Status
The current status of a broadcast can be set to communicate it to other users.
The status can be filtered at Calendar.
There are following status fields:
* **Live**: This is a live broadcast (no preproduction)
* **published**: The broadcast is scheduled and published at the public broadcast schedule
* **playout**: The preproduction has been scheduled at the playout system
* **rerun**: The broadcast is a rerun of an existing broadcast
* **archived**: the broadcast audio has been archived
=== Actions on editing a broadcast event
* edit series: change template, schedule and editors of the series
* show events: show all broadcast events of the same series
* move to other series: the broadcast will be moved to another series.
* download record: creates a temporary link to download the record.
* copy existing event: the description will be copied from an existing event to the current one.
* reminder: a mail to remind the editors will be opened in an external mail program.
* changes: shows the list of changes at the selected event
* delete: deletes the broadcast and its description
* show event: show the event at the publich program
=== Preconditions to create/add a series
* The broadcast event has to be assigned to a series.
* the broadcast time has to be inside the time slots of the selected project and studios.
* The user has to be a member of the editors of the series.
* The user needs permissiosn to "edit series he/she is assigned to"
};
}
sub check_params{
my $params=shift;
my $checked={};
my $debug=$params->{debug} || '';
if ($debug=~/([a-z\_\,]+)/){
$debug=$1;
}
$checked->{debug}=$debug;
#numeric values
$checked->{exclude}=0;
for my $param ('id', 'project_id', 'studio_id', 'default_studio_id'){
if ((defined $params->{$param})&&($params->{$param}=~/^\d+$/)){
$checked->{$param}=$params->{$param};
}
}
if (defined $checked->{studio_id}){
$checked->{default_studio_id}=$checked->{studio_id};
}else{
$checked->{studio_id}=-1;
}
return $checked;
}

View File

@@ -0,0 +1,427 @@
#! /usr/bin/perl -w
use warnings "all";
use strict;
use Data::Dumper;
use File::stat;
use Time::localtime;
use CGI qw(header param Vars escapeHTML uploadInfo cgi_error);
use URI::Escape;
use time;
use images;
use params;
use config;
use log;
use template;
use db;
use auth;
use uac;
use project;
use time;
use markup;
use studios;
use series;
use localization;
binmode STDOUT, ":utf8";
my $r=shift;
(my $cgi, my $params, my $error)=params::get($r);
$CGI::POST_MAX = 1024*10;
my $config = config::get('../config/config.cgi');
my $debug = $config->{system}->{debug};
my ($user,$expires) = auth::get_user($cgi, $config);
return if ((!defined $user) || ($user eq ''));
my $user_presets=uac::get_user_presets($config, {
user => $user,
project_id => $params->{project_id},
studio_id => $params->{studio_id}
});
$params->{default_studio_id}=$user_presets->{studio_id};
$params->{studio_id}=$params->{default_studio_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
$params->{project_id}=$user_presets->{project_id} if ((!(defined $params->{action}))||($params->{action}eq'')||($params->{action}eq'login'));
my $request={
url => $ENV{QUERY_STRING}||'',
params => {
original => $params,
checked => check_params($params),
}
};
$request = uac::prepare_request($request, $user_presets);
log::init($request);
$params=$request->{params}->{checked};
#show header
my $headerParams=uac::set_template_permissions($request->{permissions}, $params);
$headerParams->{loc} = localization::get($config, {user=>$user, file=>'menu'});
template::process('print', template::check('ajax_header.html'), $headerParams);
return unless defined uac::check($config, $params, $user_presets);
#my $base_dir = $config->{locations}->{base_dir};
my $local_media_dir = $config->{locations}->{local_media_dir};
my $local_media_url = $config->{locations}->{local_media_url};
#my $local_base_url = $config->{locations}->{local_base_url};
log::error($config, 'cannot locate media dir'.$local_media_dir) unless(-e $local_media_dir);
#continue on error
uac::permissions_denied('reading from local media dir') unless(-r $local_media_dir);
uac::permissions_denied('writing to local media dir') unless(-w $local_media_dir);
if ($params->{delete_image}ne''){
delete_image($config, $request, $user, $local_media_dir);
return;
}elsif ($params->{save_image}ne''){
save_image($config, $request, $user);
return;
}
show_image($config, $request, $user, $local_media_url);
sub show_image{
my $config=shift;
my $request=shift;
my $user=shift;
my $local_media_url=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
unless (defined $params->{project_id}){
uac::print_error("missing project id");
return undef;
}
unless (defined $params->{studio_id}){
uac::print_error("missing studio id");
return undef;
}
if($permissions->{read_image} ne '1'){
uac::permissions_denied("read image");
return 0;
}
$config->{access}->{write}=0;
my $dbh=db::connect($config,undef);
my $selectedFilename=$params->{filename}||'';
my $filenames={};
my $results=[];
# add images from series
if(defined $params->{series_id}){
my $seriesImages=series::get_images($config, $params);
for my $image (@$seriesImages){
my $filename=$image->{filename};
unless (defined $filenames->{$filename}){
#print STDERR "add1 $filename\n";
push @$results, $image;
$filenames->{$filename}=$image;
}
}
}
#load images matching by search
if(defined $params->{search}){
#remove filename from search
delete $params->{filename};
delete $params->{series_id};
my $searchImages=images::get($config, $params);
for my $image (@$searchImages){
my $filename=$image->{filename};
unless (defined $filenames->{$filename}){
#print STDERR "add2 $filename\n";
push @$results, $image;
$filenames->{$filename}=$image;
}
}
}
#load selected image, if not already loaded
if($selectedFilename ne''){
my $search =$params->{search}||'';
# use selected image if already loaded
my $selectedImage=undef;
if (defined $filenames->{$selectedFilename}){
$selectedImage=$filenames->{$selectedFilename};
}else{
#now add filename and remove search
$params->{filename}=$selectedFilename;
delete $params->{search};
#put selected image to the top
my $imagesByNames=images::get($config, $params);
$selectedImage=$imagesByNames->[0] if(scalar(@$imagesByNames)>0);
}
my $finalResults=[];
# put selected image first
$selectedFilename='not-found';
if (defined $selectedImage){
push @$finalResults, $selectedImage ;
$selectedFilename=$selectedImage->{filename};
}
# then other images
for my $image (@$results){
push @$finalResults, $image if $image->{filename} ne $selectedFilename;
}
$results=$finalResults;
#add search again
$params->{search}=$search;
}
if($params->{template}=~/edit/){
$results=[$results->[0]]||undef;
}
if (defined $results){
$results=modify_results($results, $permissions, $user, $local_media_url);
}
my $search=$params->{search}||'';
$search=~s/\%+/ /g;
my $template_params={
'search' => $search,
'images' => $results,
'count' => @$results.'',
'projects' => project::get_with_dates($config),
'project_id' => $params->{project_id},
'studio_id' => $params->{studio_id},
'filename' => $params->{filename}
};
# print STDERR
$template_params->{loc} = localization::get($config, {user=>$params->{presets}->{user}, file=>'image'});
$template_params=uac::set_template_permissions($permissions, $template_params);
#set global values for update and delete, per image values are evaluated later
$template_params->{allow}->{update_image}=$template_params->{allow}->{update_image_own}||$template_params->{allow}->{seriesupdate_image_others};
$template_params->{allow}->{delete_image}=$template_params->{allow}->{delete_image_own}||$template_params->{allow}->{delete_image_others};
template::process('print', $params->{template}, $template_params);
}
sub print_js_error{
my $message=shift;
print qq{<!--
ERROR: $message
-->
};
print STDERR $message."\n";
}
sub save_image{
my $config = shift;
my $request = shift;
my $user = shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
unless (check_permission($config, $user, $permissions, 'update_image', $params->{save_image}) eq '1'){
print_js_error("missing permission to update image");
return 0;
}
if (($params->{update_name}eq'') && ($params->{update_description}eq'')){
print_js_error("empty name or empty description!");
return 0;
}
my $image={};
$image->{filename} = $params->{save_image};
$image->{name} = $params->{update_name} if ($params->{update_name} ne'');
$image->{description} = $params->{update_description} if ($params->{update_description} ne'');
$image->{project_id} = $params->{project_id};
$image->{studio_id} = $params->{studio_id};
$image->{modified_by} = $user;
$image->{name}='new' if ($image->{name}eq'');
$config->{access}->{write}=1;
my $dbh=db::connect($config);
#print STDERR "going to save\n";
my $entries=images::get($config,{
filename => $image->{filename},
project_id => $image->{project_id},
studio_id => $image->{studio_id}
});
#print STDERR Dumper($entries);
if (scalar @$entries>1){
print_js_error('more than one matching result found');
return 0;
}
if (scalar @$entries==0){
print_js_error('image not found in database (for this studio)');
return 0;
}
my $entry=$entries->[0];
if (defined $entry){
images::update($dbh, $image);
}else{
$image->{created_by} = $user;
images::insert($dbh, $image);
}
}
sub delete_image{
my $config=shift;
my $request=shift;
my $user=shift;
my $local_media_dir=shift;
my $params=$request->{params}->{checked};
my $permissions=$request->{permissions};
unless (check_permission($config, $user, $permissions, 'delete_image', $params->{delete_image}) eq '1'){
uac::permissions_denied('delete image');
return 0;
}
#print $cgi->header();
#print "Content-type:text/html; charset=UTF-8;\n\n";
$config->{access}->{write}=1;
my $dbh=db::connect($config);
my $image={
project_id => $params->{project_id},
studio_id => $params->{studio_id},
filename => $params->{delete_image},
};
my $result=images::delete($dbh, $image);
print STDERR "delete result=".Dumper($result);
return;
my $action_result='';
my $errors='';
$result=images::delete_files($config, $local_media_dir, $params->{delete_image}, $action_result, $errors);
#use Data::Dumper;print STDERR "delete\n".Dumper($params);
print "deleted<br />$action_result<br />$errors\n";
}
sub check_permission{
my $config=shift;
my $user=shift;
my $permissions=shift;
my $permission=shift;
my $filename=shift;
return 0 unless defined $user;
return 0 if ($user eq '');
if ( $permissions->{$permission.'_others'} eq '1'){
print STDERR "$user has update_image_others\n";
return 1;
}elsif ( $permissions->{$permission.'_own'} eq '1'){
print STDERR "$user has update_image_own\n";
#check if image was created by user
my $results=images::get($config,{
filename => $filename,
created_by => $user
});
return 1 if (@$results==1);
return 0;
}
return 0;
}
sub modify_results{
my $results=shift;
my $permissions=shift;
my $user=shift;
my $local_media_url=shift;
for my $result (@$results){
unless (defined $result->{filename}){
$result=undef;
next;
}
$result->{image_url} = $local_media_url.'/images/'.$result->{filename};
$result->{thumb_url} = $local_media_url.'/thumbs/'.$result->{filename};
$result->{icon_url} = $local_media_url.'/icons/'.$result->{filename};
#reduce
for my $permission ('update_image', 'delete_image'){
if ((defined $permissions->{$permission.'_others'}) && ($permissions->{$permission.'_others'}eq'1')){
$result->{$permission}=1;
}elsif( (defined $permissions->{$permission.'_own'}) && ($permissions->{$permission.'_own'}eq'1')){
next if ($user eq'');
$result->{$permission}=1 if ($user eq $result->{created_by});
}
}
}
return $results;
}
sub check_params{
my $params=shift;
my $checked={
template => template::check($params->{template},'image.html')
};
#numeric values
$checked->{limit}=100;
for my $param ('project_id','studio_id','series_id','default_studio_id','limit'){
if ((defined $params->{$param})&&($params->{$param}=~/^\d+$/)){
$checked->{$param}=$params->{$param};
}
}
if (defined $checked->{studio_id}){
$checked->{default_studio_id}=$checked->{studio_id};
}else{
$checked->{studio_id}=-1;
}
$checked->{limit}=100 unless defined $checked->{limit};
$checked->{limit}=100 if ($checked->{limit}>100);
#string
$checked->{search}='';
if ((defined $params->{search}) && ($params->{search}=~/^\s*(.+?)\s*$/)){
$checked->{search}=$1;
}
for my $attr('update_name','update_description'){
$checked->{$attr}='';
if ((defined $params->{$attr}) && ($params->{$attr}=~/^\s*(.+?)\s*$/)){
$checked->{$attr}=$params->{$attr};
}
}
#Words
$checked->{delete_image}='';
$checked->{save_image}='';
for my $attr('save_image','delete_image','show','filename'){
$checked->{$attr}='';
if ((defined $params->{$attr}) && ($params->{$attr}=~/(\S+)/)){
$checked->{$attr}=$params->{$attr};
}
}
#map show to filename, but overwrite if filename given
if ($checked->{show}ne''){
$checked->{filename}=$checked->{show};
delete $checked->{show};
$checked->{limit}=1;
}elsif ($checked->{filename}ne''){
delete $checked->{show};
}
$checked->{from}=time::check_date($params->{from});
$checked->{till}=time::check_date($params->{till});
return $checked;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Some files were not shown because too many files have changed in this diff Show More