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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

View File

@@ -0,0 +1,415 @@
#! /usr/bin/perl
use warnings "all";
use strict;
use Data::Dumper;
use Apache2::Request;
use Apache2::Upload;
delete $INC{CGI};
require 'CGI.pm';
use Date::Calc;
use Time::Local;
use Image::Magick;
use Image::Magick::Square;
use config;
use auth;
use uac;
use studios;
use template;
use images;
binmode STDOUT, ":utf8";
my $r = shift;
my $cgi = undef;
my $config = config::get('../config/config.cgi');
our $debug = $config->{system}->{debug};
my $base_dir = $config->{locations}->{base_dir};
my $tmp_dir = '/var/tmp';
my $upload_limit = 2048*1000;
#binmode STDOUT, ":utf8";
#binmode STDOUT, ":encoding(UTF-8)";
my $params = {};
my $upload = undef;
my $error = '';
#get image from multiform before anything else
if (defined $r){
#Apache2::Request
# print "Content-type:text/html; charset=UTF-8; \n\n<br><br><br>Apache2::Request<br>\n";
my $apr = Apache2::Request->new($r, POST_MAX => $upload_limit, TEMP_DIR => $tmp_dir);
#copy params to hash
my $body=$apr->body();
if (defined $body){
for my $key (keys %$body){
# print "$key=".$apr->param($key)."<br>\n";
$params->{scalar($key)}=scalar($apr->param($key));# unless ($key eq'image');
}
}
# print Dumper($params);
# print Dumper($apr);
my $status = $apr->parse;
# print "Status:$status<br>";
$status='' if ($status=~/missing input data/i);
if ($status=~/limit/i){
$error= $status;
}else{
$upload = $apr->upload('image') if (defined $params->{image});
}
#dont get params parsed
# $CGI::POST_MAX = $upload_limit;
# $CGI::TMPDIRECTORY=$tmp_dir;
$cgi=new CGI();
# my %params=$cgi->Vars();
# $params=\%params;
# $error=$cgi->cgi_error()||$error;
}else{
#CGI fallback
# print "Content-type:text/html; charset=UTF-8; \n\n<br><br><br>CGI<br>\n";
$CGI::POST_MAX = $upload_limit;
$CGI::TMPDIRECTORY=$tmp_dir;
$cgi=new CGI();
$error=$cgi->cgi_error()||$error;
my %params=$cgi->Vars();
$params=\%params;
}
print "Content-type:text/html; charset=UTF-8;\n\n";
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);
$params = $request->{params}->{checked};
return unless defined uac::check($config, $params, $user_presets);
my $permissions=$request->{permissions};
$params->{action} ='' unless (defined $params->{action});
if($permissions->{create_image} ne '1'){
uac::permissions_denied("create image");
return 0;
}
my $file_info= undef;
if ($error ne ''){
if ($error=~/limit/){
$params->{error}.="Image size is limited to ".int($upload_limit/1000000)." MB!"
. "Please make it smaller and try again!";
}else{
$params->{error}.="Error:'$error'";
}
}elsif ($params->{action}eq'upload'){
$file_info=upload_file($config, $cgi, $upload, $user);
$params->{error}.=$file_info->{error};
$params=update_database($config, $params, $file_info, $user) if ($params->{error} eq'');
}
print STDERR $params->{error}."\n" if defined $params->{error};
my $out='';
template::process('print', $params->{template}, $params);
print $cgi->cgi_error() if defined $cgi;
#return;
return if($params->{action} eq '');
if ($params->{error} eq''){
print qq{
<div id="output">success</div>
<div id="message">
$params->{action_result}
{{thumbs//$params->{filename}}}
<button onclick="selectThisImage('$params->{filename}')">assign to event</button>
</div>
<div id="upload_image_id">$params->{image_id}</div>
<div id="upload_image_filename">$params->{filename}</div>
<div id="upload_image_title">$params->{name}</div>
<div id="upload_image_link">{{thumbs//$params->{filename}}}</div>
};
}else{
print qq{
<div id="output">failed</div>
<div id="message">$params->{error}</div>
};
}
sub upload_file{
my $config = shift;
my $cgi = shift;
my $upload = shift;
my $user = shift;
my $result = get_filename($cgi, $upload);
return $result if ($result->{error} ne '');
my $file = $result->{fh};
my $filename = $result->{filename};
$result=check_filename($filename);
print STDERR $result."\n";
return $result if ($result->{error} ne '');
my $extension=$result->{extension}||'';
#read file from handle
my $data;
my $content='';
print STDERR $file."\n";
#unless (-e $file){}
binmode $file;
while(read $file,$data,1024) {
$content.=$data;
}
#set filename to MD5 from content
my $md5_filename=Digest::MD5::md5_base64($content);
$md5_filename=~s/[\/\+]/_/gi;
return process_image($config, $filename, $extension, $md5_filename, $content);
}
sub update_database{
my $config=shift;
my $params=shift;
my $file_info=shift;
my $user=shift;
$params->{upload_path} = $file_info->{upload_path};
$params->{upload_filename} = $file_info->{upload_filename};
$params->{filename} = $file_info->{filename};
$params->{thumb_path} = $file_info->{thumb_path};
$params->{image_path} = $file_info->{image_path};
$params->{icon_path} = $file_info->{icon_path};
$params->{local_media_url} = $config->{locations}->{local_media_url};
my $name=$params->{name}||'';
$name='neu' unless $params=~/\S/;
my $image={
filename => $params->{filename},
name => $params->{name}||'new',
description => $params->{description},
modified_by => $user,
project_id => $params->{project_id},
studio_id => $params->{studio_id}
};
#connect
$config->{access}->{write}=1;
my $dbh=db::connect($config);
my $entries=images::get($config, { filename => $image->{filename} } );
if ((defined $entries)&&(@$entries>0)){
images::update($dbh, $image);
my $entry=$entries->[0];
$params->{image_id}=$entry->{id};
}else{
$image->{created_by} = $user;
$params->{image_id}=images::insert($dbh, $image);
}
$config->{access}->{write}=0;
$params->{action_result}='done!';
return $params;
}
#get filename and filehandle from upload
sub get_filename{
my $cgi=shift;
my $upload=shift;
if (defined $upload){
# try apache2 module
my $filename=$upload->filename();
return {
filename => $filename,
fh => $upload->fh(),
error => ''
};
}
# fallback to CGI module
my $file = $cgi->param("image");
if ($file=~/\|/){
return { error => "is no file" };
}
my $file_info=$cgi->uploadInfo($file);
if (defined $file_info){
my $filename=$file_info->{'Content-Disposition'}||'';
if ($filename=~/filename=\"(.*?)\"/){
$filename=$1;
return {
filename => $filename,
fh => $file,
error => ''
};
}
}
#error
return {
error=>'Could not detect file name!'
};
}
sub check_filename{
my $filename=shift;
my @valid_extensions=('png', 'jpeg', 'jpg', 'gif', 'pdf', 'txt', 'bmp', 'ps', 'eps', 'wmf');
if($filename =~ /\.([a-zA-Z]{3,5})$/){
my $extension = lc $1;
unless(grep(/$extension/,@valid_extensions)) {
return {
error => 'Following file formats are supported: '.join(",",@valid_extensions).'!'
};
}
return{
extension => $extension,
error => ''
};
}else{
return {
error => 'Not matching file extension found! Supported are: '.join(",",@valid_extensions).'!'
};
}
}
sub process_image{
my $config = shift;
my $filename = shift;
my $extension = shift;
my $md5_filename = shift;
my $content = shift;
my $upload_path = $config->{locations}->{local_media_dir}.'upload/'.$md5_filename.'.'.$extension;
my $thumb_path = $config->{locations}->{local_media_dir}.'thumbs/'.$md5_filename.'.jpg';
my $icon_path = $config->{locations}->{local_media_dir}.'icons/'.$md5_filename.'.jpg';
my $image_path = $config->{locations}->{local_media_dir}.'images/'.$md5_filename.'.jpg';
#copy file to upload space
open DAT,'>'.$upload_path or return {error=> 'could not save image. '.$!." $upload_path"};
binmode DAT;
print DAT $content;
close DAT;
#write image
my $image = new Image::Magick;
$image->Read($upload_path);
my $x=$image->Get('width')||0;
my $y=$image->Get('height')||0;
if(($x==0) || ($y==0)){
return {error=>'Could not read image!'};
log::error($config, 'Cannot read image $filename!');
};
#set max size image
if ($x>0 && $y>0){
if ($x>$y){
$image->Resize(width=>'600', height=>int(600*$y/$x) );
}else{
$image->Resize(width=>int(600*$x/$y), height=>'600');
}
}
#$image->Normalize();
$image->Write('jpg:'.$image_path);
#write thumb
my $thumb=$image;
$thumb->Trim2Square;
$thumb->Resize(width=>150,height=>150);
$thumb->Write('jpg:'.$thumb_path);
my $icon=$image;
$icon->Trim2Square;
$icon->Resize(width=>25,height=>25);
$icon->Write('jpg:'.$icon_path);
unless(-e $thumb_path){
return {error=>'could not create thumb nail file!'};
}
unless(-e $icon_path){
return {error=>'could not create icon file!'};
}
unless(-e $image_path){
return {error=>'could not create image file!'};
}
return {
upload_filename =>$filename,
filename =>$md5_filename.'.jpg',
thumb_path =>$thumb_path,
icon_path =>$icon_path,
image_path =>$image_path,
error =>''
};
}
sub check_params{
my $params=shift;
my $checked={};
$checked->{template} = template::check($params->{template},'imageUpload');
#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;
}
#string
for my $param ('debug','name','description'){
if ((defined $params->{$param}) && ($params->{$param}=~/^\s*(.+?)\s*$/)){
$checked->{$param}=$1;
}
}
#Words
for my $attr('action'){
if ((defined $params->{$attr}) && ($params->{$attr}=~/(\S+)/)){
$checked->{$attr}=$params->{$attr};
}
}
return $checked;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

View File

@@ -0,0 +1 @@
calendar.cgi

View File

@@ -0,0 +1,337 @@
function getController(){
var url=window.location.href;
var parts=url.split('.cgi');
url=parts[0];
var parts=url.split('/');
var usecase=parts[parts.length-1];
return usecase;
}
function set_studio(id){
var url=window.location.href;
//split by #
var comment= url.split(/\#/);
url=comment.shift();
comment=comment.join('#');
//split by ?
var parts= url.split(/\?/);
url=parts.shift();
//split by &
parts=parts.join('?').split(/\&+/);
var params=[];
if (parts.length>0){
for (index in parts){
//add all name value pairs but studio id
var pair=parts[index];
if(! pair.match(/^studio_id=/)) params.push(pair);
}
}
//add studio id
if(id==null)id=-1;
if(id=='')id=-1;
params.push('studio_id='+id);
//append parameters to url
url+='?'+params.join('&');
if ((comment!=null)&&(comment!='')) url+='#'+comment;
window.location.href=url;
}
function set_project(id){
var url=window.location.href;
//split by #
var comment= url.split(/\#/);
url=comment.shift();
comment=comment.join('#');
//split by ?
var parts= url.split(/\?/);
url=parts.shift();
//split by &
parts=parts.join('?').split(/\&+/);
var params=[];
if (parts.length>0){
for (index in parts){
//add all name value pairs but project id
var pair=parts[index];
if(
(! pair.match(/^project_id=/))
&& (! pair.match(/^studio_id=/))
)params.push(pair);
}
}
//add project id
if(id==null)id=-1;
if(id=='')id=-1;
params.push('project_id='+id);
//append parameters to url
url+='?'+params.join('&');
if ((comment!=null)&&(comment!='')) url+='#'+comment;
window.location.href=url;
}
function contains(s,t){
if (s==false) return false;
if (t==false) return false;
return s.indexOf(t) != -1;
}
function updateContainer(id, url, callback){
//alert(id+":"+url);
if (id==null) return;
if ($("#"+id).length==0) return;
$("#"+id).load(url, callback);
}
function load(url){
window.location=url;
//window.location.replace(url);
//document.location.href=url;
//$(window).load(url);
//$('html').load(url);
}
function postContainer(url, parameters, callback){
if (url!='') $.post(url, parameters, callback);
}
// init getTextWidth
function initTextWidth(){
if ($('#textWidth').length>0) return;
$('#content').append('<span id="textWidth" style="padding:0;margin:0;visibility:hidden; white-space:nowrap;"></span>')
}
// get width of selected text
function getTextWidth(s){
$("#textWidth").html(s);
return $("#textWidth").width();
}
// check width of all selected elements and set width to max of it
function setTextWidth(select, minValue){
var maxWidth=minValue;
$(select).each(
function(){
var width=getTextWidth($(this).val())-8;
if (width>maxWidth) maxWidth=width;
}
);
$(select).each(
function(){
$(this).css('width', maxWidth);
}
);
}
// trigger action on commit
function commitAction (title, action){
if (action==null) {alert("missing action");return}
if (title==null) {alert("missing title");return}
if ($("#dialog-confirm").length>0) $("#dialog-confirm").remove();
$("#content").append(
'<div id="dialog-confirm" title="'+title+'" style="min-height:2em;">'
+'<p>'
+'<span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>'
+'Are you sure?'
+'</p>'
+'</div>'
);
$( "#dialog-confirm" ).dialog({
resizable: false,
height: "200",
modal: true,
buttons: {
Okay : function() {
$(this).dialog( "close" );
action();
},
Cancel: function() {
$(this).dialog( "close" );
}
}
});
}
// set action=<action> at form and submit the form after confirmation
function commitForm ( formElement, action, title){
if (formElement==null) { alert("missing id");return }
if (action==null) { alert("missing action");return }
if (title==null) { alert("missing title");return }
formElement='#'+formElement;
if ($(formElement).length!=1) {alert("id "+formElement+" exists not only once, but "+$(formElement).length+" times");return}
if ($(formElement).is('form')==0) {alert("id "+formElement+" this is not a form");return}
commitAction(title,
function(){
$(formElement).append('<input type="hidden" name="action" value="'+action+'">');
$(formElement).submit();
}
);
}
function setUrlParameter(url, name, value){
if(url==null) url=window.location.href;
//separate url and comments
var comments=url.split('#');
url=comments.shift();
var comment=comments.join('#');
url=removeUrlParameter(url,name);
if(!contains(url,'?')) url+='?';
//add parameter
url+='&'+name+'='+encodeURIComponent(value);
url=url.replace('?&','?');
//add comments
if ((comments!=null) && (comments!='') )url+='#'+comments;
return url;
}
function removeUrlParameter(url, name){
var r = new RegExp("[\\?]"+name+"=[^&#]*");
url=url.replace(r,'?');
var r = new RegExp("&"+name+"=[^&#]*");
url=url.replace(r,'');
return url;
}
function getUrlParameter(name){
var r = new RegExp("[\\?&]"+name+"=([^&#]*)")
var results = r.exec( window.location.href );
if( results == null )return null;
return results[1];
}
// will be overridden by calendar.js
function setupMenuHeight(){
//$('#content').css("position", "absolute");
/*
var top = $('#calcms_admin_menu').height();
$('#content').css("top", top);
var left=0;
if( $(window).width() >= $(document).width() ){
left=$(document).width()-$('#content').width();
left/=2;
if (left<40)left=0;
}
$('#content').css("left", left);
*/
return top;
}
function getProjectId(){
return $('#project_id').val();
}
function getStudioId(){
return $('#studio_id').val();
}
//set project id and studio id
function setMissingUrlParameters(){
console.log("check");
var project_id=$('#project_id').val();
var studio_id =$('#studio_id').val();
if (project_id==null) project_id='';
if (studio_id==null) studio_id='';
if(
( project_id != getUrlParameter('project_id') )
|| ( studio_id != getUrlParameter('studio_id') )
){
var project_id=$('#project_id').val();
var studio_id=$('#studio_id').val();
var url=window.location.href;
if(project_id==null){
console.log("check called too fast");
return;
}
if(studio_id==null){
console.log("check called too fast");
return;
}
url=setUrlParameter(url, 'project_id', project_id);
url=setUrlParameter(url, 'studio_id', studio_id);
load(url);
}
}
function checkSession(){
var datetime=$('#logout').attr('expires');
if(datetime=='')return;
var date1=parseDateTime(datetime);
if(date1==null)return;
if(date1.getTime()<0)return;
var intervalID = setInterval(
function(){
var now = new Date().getTime();
var expiry = Math.floor((date1.getTime() - now) / 1000);
$('#logout').attr('title', "session expires in "+expiry+" seconds");
if (expiry<120){
alert("session expires soon!");
}
if (expiry<0){
alert("session expired!");
clearInterval(intervalID);
}
}, 5000
);
}
function checkLabel(element){
var value=element.val();
console.log(">"+value+"<");
if (value==''){
element.parent().find('div.label').hide();
element.css("padding-top","8px");
}else{
element.parent().find('div.label').show();
element.css("padding-top","0");
}
}
function initLabels(){
var selector='div.formField input';
$(selector).each(function(){
checkLabel($(this));
$(selector).keyup(function(){checkLabel($(this));});
});
};
$(document).ready(
function(){
checkSession();
setMissingUrlParameters();
if(getController()=='calendar'){
//use build-in localization
console.log("add back")
addBackButton();
return;
}else{
//use javascript localization
setupLocalization(function(){
addBackButton();
});
}
initLabels();
//setupMenuHeight();
//$(window).resize(function() {
//setupMenuHeight();
//});
}
);

View File

@@ -0,0 +1,15 @@
function download(id, name){
//alert(id +" "+ name);
$.getJSON(
'archive.cgi?get_link='+name,
function(data){
//alert(data);
$.each(data,
function(key, val) {
$('#'+id).html(val);
}
);
}
);
}

View File

@@ -0,0 +1,17 @@
function showProgress(){
$('#progress').slideDown();
return false;
}
function playAudio(path){
var url='../../agenda_files/recordings/'+path;
var win = window.open(url, '_blank');
}
$( document ).ready(
function() {
var number = 1+Math.floor(11 * Math.random());
$('#progress img').attr("src", "/agenda/image/upload/bird"+number+".gif");
}
);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,128 @@
function showCommentsByAge(age){
var url='comment.cgi?';
url += '&project_id='+getProjectId();
url += '&studio_id='+getStudioId();
url += '&age='+age;
window.location.href=url;
}
function showEventComments(eventId){
var elemId="event_"+eventId+"_comments";
var element=$("#"+elemId);
if (element.css('display')=='none'){
loadComments(eventId, function(){
scrollToComment(eventId);
});
}else{
hideComments(elemId);
}
return false;
}
function loadComments(eventId, callback){
var url='comment.cgi?';
url += '&action=showComment';
url += '&project_id='+getProjectId();
url += '&studio_id='+getStudioId();
url += '&event_id='+eventId;
//console.log(url);
var elemId="event_"+eventId+"_comments";
var element=$("#"+elemId);
element.load(
url,
function(){
showComments(elemId);
if(callback!=null){
//console.log("callback");
callback();
}
}
);
}
function showComments(elemId){
var element=$("#"+elemId);
if(element.is("tr")){
element.css("display","table-row");
return;
}else{
element.slideDown();
}
//console.log("autosize");
$("#comments textarea").autosize();
}
function hideComments(elemId){
//console.log("hide comments for "+elemId);
var element=$("#"+elemId);
if(element.is("tr")){
element.css("display","none");
element.empty();
return;
}else{
element.slideUp("normal",function(){
element.empty();
});
}
}
function scrollToComment(eventId){
$('html, body').animate({
scrollTop: $("#event_"+eventId+"_comments").offset().top - 100
}, 2000
);
}
function setCommentStatusRead(commentId, eventId, status){
var url='comment.cgi?'
url += '&action=setRead';
url += '&readStatus='+status;
url += '&project_id='+getProjectId();
url += '&studio_id='+getStudioId();
url += '&event_id='+eventId;
url += '&comment_id='+commentId;
//console.log(url);
$("#event_"+eventId+"_comments").load(
url,
function(){
loadComments(
eventId,
function(){
scrollToComment(eventId);
}
);
}
);
return false;
}
function setCommentStatusLock(commentId,eventId,status){
var url='comment.cgi?'
url += '&action=setLock';
url += '&lockStatus='+status;
url += '&project_id='+getProjectId();
url += '&studio_id='+getStudioId();
url += '&event_id='+eventId;
url += '&comment_id='+commentId;
//console.log(url);
$("#event_"+eventId+"_comments").load(
url,
function(){
loadComments(
eventId,
function(){
scrollToComment(eventId);
}
);
}
);
return false;
}

View File

@@ -0,0 +1,222 @@
// wrapper for date time picker with callback function
function showDateTimePicker(selector, options){
$(selector).each( function(){
// init on first select
$(this).on('click', function(){
if ($(this).hasClass("hasDatepicker")) return;
var defaultOptions={
dateFormat: "yy-mm-dd",
timeFormat: "HH:mm",
stepMinute: 5,
firstDay: 1,
showOtherMonths: true,
selectOtherMonths: true,
changeMonth: true,
changeYear: true,
showWeek: true,
}
//recursively merge options
$.extend(true, defaultOptions, options);
$(this).datetimepicker(defaultOptions);
// set date and time from input field
var datetime=$(this).attr('value');
if ((datetime != null) && (datetime != "")){
var datetime=parseDateTime(datetime);
$(this).datetimepicker('setDate', datetime);
$(this).datetimepicker('setTime', datetime);
}
if((region !=null) && (region !='' ) && (region != 'en')){
$(this).datetimepicker( $.timepicker.regional[ region+"" ] );
}
//show if has been initialized on first click
$(this).focus();
});
});
}
// show date picker on first select with callback function
function showDatePicker(selector, options){
$(selector).each( function(){
// init on first select
var activator=$(this);
if ((options!=null)&&(options.activator!=null)) activator=$(options.activator);
activator.on('click', function(){
if ($(this).hasClass("hasDatepicker")) return;
var defaultOptions={
dateFormat: "yy-mm-dd",
timeFormat: "HH:mm",
showTimePicker: false,
firstDay: 1,
showOtherMonths: true,
selectOtherMonths: true,
changeMonth: true,
changeYear: true,
showWeek: true,
}
//recursively merge options
$.extend(true, defaultOptions, options);
$(this).datepicker(defaultOptions);
// set date from input field
var datetime=$(this).attr('value');
if ((datetime != null) && (datetime != "")){
$(this).datepicker('setDate', datetime);
}
if((region !=null) && (region !='' ) && (region != 'en')){
$(this).datepicker( $.datepicker.regional[ region+"" ] );
}
//show if has been initialized on first click
$(this).focus();
});
});
}
// date picker with direct registration
function registerDatePicker(selector, options){
$(selector).each( function(){
var defaultOptions={
dateFormat: "yy-mm-dd",
timeFormat: "HH:mm",
showTimePicker: false,
firstDay: 1,
showOtherMonths: true,
selectOtherMonths: true,
changeMonth: true,
changeYear: true,
showWeek: true,
}
//recursively merge options
$.extend(true, defaultOptions, options);
$(this).datepicker(defaultOptions);
// set date from input field
var datetime=$(this).attr('value');
if ((datetime != null) && (datetime != "")){
$(this).datepicker('setDate', datetime);
}
if((region !=null) && (region !='' ) && (region != 'en')){
$(this).datepicker( $.datepicker.regional[ region+"" ] );
}
//show if has been initialized on first click
$(this).focus();
});
}
function showYearPicker(selector, options){
$(selector).each( function(){
var year=new Date().getYear()+1900;
var html='<select>';
for (var i=year-10; i<year+10; i++){
var selected='';
if (i==year) selected=' selected="selected"';
html+='<option value="'+i+'"'+selected+'>'+i+'</option>';
}
html+='</select>';
$(selector).html(html);
if (options.onSelect != null){
$(selector+' select').on('change', options.onSelect);
};
})
}
function parseDateTime(datetime){
var dateTime = datetime.split(/[ T]+/);
var date = dateTime[0].split("-");
var yyyy = date[0];
var mm = date[1]-1;
var dd = date[2];
var h=0;
var m=0;
var s=0;
if (dateTime.length>1){
var time = dateTime[1].split(":");
h = time[0];
m = time[1];
s = 0;
}
return new Date(yyyy,mm,dd,h,m,s);
}
function formatDateTime(datetime){
var string= 1900+datetime.getYear()+'-';
if (datetime.getMonth()<10) { string+='0'+(datetime.getMonth()+1) } else {string+=(datetime.getMonth()+1) };
string+='-'
if (datetime.getDate()<10) { string+='0'+datetime.getDate() } else {string+=datetime.getDate() };
string+=' '
if (datetime.getHours()<10) { string+='0'+datetime.getHours() } else {string+=datetime.getHours() };
string+=':'
if (datetime.getMinutes()<10){ string+='0'+datetime.getMinutes()} else {string+=datetime.getMinutes()};
return string;
}
function formatDate(datetime){
var string= 1900+datetime.getYear()+'-';
if (datetime.getMonth()<9) { string+='0'+(datetime.getMonth()+1) } else {string+=(datetime.getMonth()+1) };
string+='-'
if (datetime.getDate()<10) { string+='0'+datetime.getDate() } else {string+=datetime.getDate() };
return string;
}
function formatTime(datetime){
var string= '';
if (datetime.getHours()<10) { string+='0'+datetime.getHours() } else {string+=datetime.getHours() };
string+=':'
if (datetime.getMinutes()<10){ string+='0'+datetime.getMinutes()} else {string+=datetime.getMinutes()};
return string;
}
//todo: separate weekday and formating
function addMinutes(datetime, minutes){
var startDate=parseDateTime(datetime);
var endDate=new Date(startDate.getTime()+minutes*60*1000);
var weekday=getWeekday(endDate);
var formatedDate=weekday+" "+formatDateTime(endDate);
return formatedDate;
}
function addHours(datetime, hours){
var startDate=parseDateTime(datetime);
var endDate=new Date(startDate.getTime()+hours*60*60*1000);
return endDate;
}
function addDays(datetime, days){
var startDate=parseDateTime(datetime);
var endDate=new Date(startDate.getTime()+days*24*60*60*1000);
return endDate;
}
var weekdays=['Mo','Di','Mi','Do','Fr','Sa','So'];
function getWeekday(date){
if (loc['weekday_Mo']!=null) weekdays[0]=loc['weekday_Mo'];
if (loc['weekday_Tu']!=null) weekdays[1]=loc['weekday_Tu'];
if (loc['weekday_We']!=null) weekdays[2]=loc['weekday_We'];
if (loc['weekday_Th']!=null) weekdays[3]=loc['weekday_Th'];
if (loc['weekday_Fr']!=null) weekdays[4]=loc['weekday_Fr'];
if (loc['weekday_Sa']!=null) weekdays[5]=loc['weekday_Sa'];
if (loc['weekday_Su']!=null) weekdays[6]=loc['weekday_Su'];
//console.log(weekdays);
return weekdays[(date.getDay()-1+7)%7]+','
}

View File

@@ -0,0 +1,305 @@
function updateCalendarLink(){
var link=$('a#menu_calendar');
var url=link.attr('href');
date=$('#start_date').attr('value');
date=parseDateTime(date);
date=formatDate(date);
url=setUrlParameter(url, "date", date);
link.attr('href',url);
}
function onDateModified(){
var value=addMinutes($('#start_date').val(), $('#duration').val());
$('#end_date').html(value);
var startDate=parseDateTime($('#start_date').val());
var weekday=getWeekday(startDate);
$('#start_date_weekday').html(weekday);
updateCalendarLink();
}
function selectRerun(resultSelector, tillDate){
$('#selectRerun').show();
//$('#selectRerun input:radio').attr("value","0");
//$('#selectRerun input:radio').prop("checked",false);
$('#selectRerun input:radio.default').attr("value","1");
$('#selectRerun input:radio.default').prop("checked",true);
$('#selectRerun input:radio.default').click();
$('.buttons').hide();
}
// hide buttons and events
function hideSelectRerun(resultSelector, tillDate){
$('#selectRerun').hide();
$('#import_rerun_header').hide('slideUp');
$('#import_rerun').hide();
$('.buttons').show();
$('#edit_event').show();
}
function selectOldEventFromSeries(resultSelector, tillDate){
$('#edit_event').hide();
$('#import_rerun').show();
$('#import_rerun_header').show('slideUp');
if ($('#import_rerun_header').css('display')=='none')return;
var url='selectEvent.cgi?'
url+='project_id='+getProjectId();
url+='&studio_id='+getStudioId();
url+='&series_id='+getUrlParameter('series_id');
url+='&event_id='+getUrlParameter('event_id');
url+="&resultElemId="+encodeURIComponent(resultSelector);
url+="&till_date="+tillDate;
url+="&selectRange=1";
updateContainer('import_rerun', url);
}
function selectOtherEvent(resultSelector){
$('#edit_event').hide();
$('#import_rerun').show();
$('#import_rerun_header').show('slideUp');
if ($('#import_rerun_header').css('display')=='none')return;
var url='selectEvent.cgi?'
url+='project_id='+getProjectId();
url+='&studio_id='+getStudioId();
url+='&series_id='+getUrlParameter('series_id');
url+='&event_id='+getUrlParameter('event_id');
url+="&resultElemId="+encodeURIComponent(resultSelector);
url+="&selectRange=1";
url+="&selectProjectStudio=1";
url+="&selectSeries=1";
updateContainer('import_rerun', url);
}
function copyFromEvent(resultSelector){
resultSelector='#'+resultSelector;
var eventId=$(resultSelector).val();
if (eventId<=0){
alert("no valid event selected");
return
}
var projectId = $('#selectEvent #projectId').val();
var studioId = $('#selectEvent #studioId').val();
var seriesId = $('#selectEvent #seriesId').val();
var eventId = $('#selectEvent #eventId').val();
loadEvent(projectId, studioId, seriesId, eventId, function(){
hideSelectRerun();
});
}
function loadEvent(projectId,studioId,seriesId,eventId, callback){
var url="event.cgi";
url+="?project_id="+projectId;
url+="&studio_id="+studioId;
url+="&series_id="+seriesId;
url+="&event_id="+eventId;
url+="&action=get_json";
url+="&json=1";
url+="&get_rerun=1";
console.log("loadEvent: "+url)
$.getJSON( url, function( event ) {
$("#edit_event input[name='title']").attr('value', event.title)
$("#edit_event input[name='user_title']").attr('value', event.user_title)
$("#edit_event input[name='episode']").attr('value', event.episode)
updateCheckBox( "#edit_event input[name='live']", event.live);
updateCheckBox( "#edit_event input[name='published']", event.published);
updateCheckBox( "#edit_event input[name='archived']", event.archived);
updateCheckBox( "#edit_event input[name='rerun']", event.rerun);
updateCheckBox( "#edit_event input[name='playout']", event.playout);
$("#edit_event textarea[name='excerpt'").html(event.excerpt);
$("#edit_event textarea[name='user_excerpt'").html(event.user_excerpt);
$("#edit_event textarea[name='topic']").html(event.topic);
$("#edit_event textarea[name='content']").html(event.content);
updateImage("#edit_event input[name='image']", event.image);
$("#edit_event input[name='podcast_url']").attr('value', event.podcast_url);
$("#edit_event input[name='archive_url']").attr('value', event.archive_url);
updateDuration("#edit_event #duration", event.duration);
if (callback!=null) callback();
console.log("loadEvent done")
});
}
// load series selection
function selectChangeSeries(resultSelector){
var url='selectSeries.cgi?'
url+='project_id='+getProjectId();
url+='&studio_id='+getStudioId();
url+='&series_id='+getUrlParameter('series_id');
url+="&resultElemId="+encodeURIComponent(resultSelector);
url+="&selectSeries=1";
//console.log(url);
updateContainer('changeSeriesContainer', url, function(){
$('#selectSeries').removeClass('panel');
$('#selectChangeSeries').addClass('panel');
$('div.buttons').hide();
$('#selectChangeSeries').show('slideUp');
});
}
// will be fired on updatine resultSelector of series selection
function changeSeries(seriesId){
var projectId= $('#selectSeries #projectId').val();
var studioId= $('#selectSeries #studioId').val();
var seriesId= getUrlParameter('series_id');
var eventId= getUrlParameter('event_id');
var newSeriesId= $('#changeSeriesId').val();
if (projectId <=0 ) return;
if (studioId <=0 ) return;
if (seriesId <=0 ) return;
if (eventId <=0 ) return;
if (newSeriesId <=0 ) return;
$('div.buttons').show();
$('#selectChangeSeries').hide('slideUp');
console.log('move to '+projectId+', '+studioId+', '+seriesId+', '+eventId+' -> series '+newSeriesId);
var url='series.cgi?';
url += '&project_id='+projectId;
url += '&studio_id='+studioId;
url += '&series_id='+seriesId;
url += '&event_id='+eventId;
url += '&new_series_id='+newSeriesId;
url += '&action=reassign_event';
$.post(
url,
function(data){
var url='event.cgi?';
url += '&project_id='+projectId;
url += '&studio_id='+studioId;
url += '&series_id='+newSeriesId;
url += '&event_id='+eventId;
url += '&action=edit';
window.location.href = url;
}
);
return false;
}
// hide change series on abort
function hideChangeSeries(){
$('#selectChangeSeries').hide('slideUp');
$('#changeSeriesContainer').html('');
$('div.buttons').show();
}
var durationUpdated=0;
function updateDuration(selector, value){
$(selector+" option").each(function(){
if ($(this).attr('value')==value){
$(this).attr('selected','selected');
durationUpdated=1;
//console.log("updated "+value)
}else{
$(this).removeAttr('selected');
//console.log("removed "+value)
}
})
if(durationUpdated==0){
console.log("added "+value)
$(selector).append('<option value="'+value+'">'+value+'</option>');
}
}
function updateImage(selector, value){
value=value.replace("http://","//");
$(selector).attr('value', value);
$(selector).parent().find('button img').attr('src',value);
}
function updateCheckBox(selector, value){
$(selector).attr('value', value)
if (value==1){
$(selector).prop( "checked", true );
} else {
$(selector).prop( "checked", false );
}
}
function checkExcerptField(){
var elem=$('textarea[name="excerpt"]');
if (elem.length==0) return 0;
var length = elem.val().length;
console.log("length="+length);
if (length > 250){
$('#excerpt_too_long').show();
}else{
$('#excerpt_too_long').hide();
}
return 1;
}
function checkExcerptExtensionField(){
var elem=$('textarea[name="user_excerpt"]');
if (elem.length==0) return 0;
var length = elem.val().length;
console.log("length="+length);
if (length > 250){
$('#excerpt_extension_too_long').show();
}else{
$('#excerpt_extension_too_long').hide();
}
return 1;
}
function checkFields(){
if (checkExcerptField()){
$('textarea[name="excerpt"]').on("keyup", function(){
checkExcerptField();
});
}
if (checkExcerptExtensionField()){
$('textarea[name="user_excerpt"]').on("keyup", function(){
checkExcerptExtensionField();
});
}
}
$(document).ready(
function(){
initRegions(region);
showDateTimePicker('#start_date');
$('input[type="checkbox"]').click(
function(){
if ($(this).attr('value')=='1'){
$(this).attr('value','0');
}else{
$(this).attr('value','1');
}
}
);
if($('#calendar').length==0){
$('#back_to_calendar').hide();
}
onDateModified();
pageLeaveHandler();
checkFields();
$('textarea').autosize();
console.log("done")
}
);

View File

@@ -0,0 +1,63 @@
function editImage(filename){
$("#img_editor").load('image.cgi?show='+filename+'&template=image_edit.html',
function(){
$('#img_editor').dialog({
width:920,
height:330
});
}
);
}
function showImage(url){
$("#img_image").html('<img src="'+url+'" onclick="$(\'#img_image\').dialog(\'close\');return false;"/>');
$("#img_image").dialog({
width:640,
height:640
});
}
function hideImageDetails(id,filename){
try{$('#img_editor').dialog('close');}catch(e){}
try{$('#img_image').dialog("close");}catch(e){}
$("#"+id).load('image.cgi?show='+filename+'&template=image_single.html');
return false;
}
function saveImage(id, filename) {
var url='image.cgi?save_image='+filename;
if (url!='') $.post(
url,
$("#save_img_"+id).serialize(),
function(data){
hideImageDetails('img_'+id, filename);
}
);
return false;
}
function deleteImage(id, filename) {
$("#"+id).load('image.cgi?delete_image='+filename);
hideImageDetails('img_'+id, filename);
$("#"+id).hide('drop');
return false;
}
function showImageUrl(id){
var el=document.getElementById(id);
var input_id=id+'_input';
var text='<input id="'+input_id+'" value="{{thumbs/'+id+'|title}}" title="3fach-Klick zum Markieren!">';
if (el.innerHTML==text){
el.innerHTML='';
}else{
el.innerHTML=text;
var input=document.getElementById(input_id);
input.focus();
input.select();
input.createTextRange().execCommand("Copy");
}
return false;
}

View File

@@ -0,0 +1,279 @@
/*
show a series, its template, users and events
*/
// set checkbox values checked depending on value
function initCheckBoxes(){
$('div.editor input[type="checkbox"]').each(
function () {
if ($(this).attr('value')=='1'){
$(this).attr('value','1');
$(this).attr('checked','checked');
}else{
$(this).attr('value','0');
$(this).attr('checked',null);
}
}
);
}
// add checkbox handler to change value on click
function addCheckBoxHandler(){
$('div.editor input[type="checkbox"]').click(
function () {
if ($(this).attr('value')=='1'){
$(this).attr('value','0');
}else{
$(this).attr('value','1');
}
}
);
}
// show/hide series member edit
function edit_series_members(series_id){
$('.edit_series_members_'+series_id).toggle();
}
// show/hide schedule fields depending on period type for a given schedule element
function showScheduleFields(id){
var select='#'+id+' select[name="period_type"]';
var type=$(select).val();
//hide and show values for different schedule types
if (type=='single'){
$('#'+id+' div.cell.frequency').hide();
$('#'+id+' div.cell.end').hide();
$('#'+id+' div.cell.schedule_weekday').hide();
$('#'+id+' div.cell.week_of_month').hide();
$('#'+id+' div.cell.schedule_month').hide();
$('#'+id+' div.cell.nextDay').hide();
}else if(type=='days'){
$('#'+id+' div.cell.frequency').show();
$('#'+id+' div.cell.end').show();
$('#'+id+' div.cell.schedule_weekday').hide();
$('#'+id+' div.cell.week_of_month').hide();
$('#'+id+' div.cell.schedule_month').hide();
$('#'+id+' div.cell.nextDay').hide();
}else if(type=='week_of_month'){
$('#'+id+' div.cell.frequency').hide();
$('#'+id+' div.cell.end').show();
$('#'+id+' div.cell.schedule_weekday').show();
$('#'+id+' div.cell.week_of_month').show();
$('#'+id+' div.cell.schedule_month').show();
$('#'+id+' div.cell.nextDay').show();
}
}
// show/hide schedule fields for all schedules
function initScheduleFields(){
$('div.row.schedule form').each(function(){
var id = $(this).attr('id');
if(contains(id,'schedule_'))showScheduleFields(id);
});
}
// preselect options in select boxes
function setSelectedOptions(){
$('#tabs-schedule select').each(
function(){
var value=$(this).attr('value');
if (value==null) return;
if (value=='') return;
$(this).children().each(
function(){
if ($(this).attr('value')==value){
$(this).attr('selected','selected');
}
}
);
}
);
}
function initSelectChangeHandler(selector, name, title){
$(selector).each(
function(){
//replace select by input, if no matching field
var value=$(this).attr('value');
//check if a child is selected
var found=0;
$(this).children().each(function(){
if (found==1) return;
if ($(this).attr('value')==value){
found=1;
$(this).attr('selected');
}else{
$(this).removeAttr('selected');
}
});
if(found==1){
return;
}
// find option with empty value
$(this).children().each(function(){
if ($(this).attr('value')==''){
// add selected option
$(this).parent().append('<option value="'+value+'" selected="1">'+value+' Min</option>');
// add option to edit field
$(this).parent().append(
loc[title]+'<br>'+'<input name="'+name+'" value="'+value+'" class="'+name+'">'
);
}
});
setInputWidth();
}
);
}
//add handler to replace select boxes by input fields if choosen value is empty
function addSelectChangeHandler(selector, name, title){
$(selector).each(
function(){
$(this).change(function(){
if($(this).val()==''){
//replace select by input, copy value from select to input,
var value=$(this).attr('value');
$(this).parent().html(
loc[title]+'<br>'
+'<input name="'+name+'" value="'+value+'" class="'+name+'">'
);
}else{
//set selected value to select
$(this).attr('value',$(this).val());
}
setInputWidth();
});
}
);
}
// print selected weekday before datetime picker
function updateWeekdays(){
$('.schedule input.datetimepicker.start').each(
function(){
var weekday=getWeekday(parseDateTime($(this).val()));
if (weekday==null) weekday='';
if (weekday=='undefined,') weekday='';
$(this).parent().prev().html(weekday);
}
);
$('#tabs-events td.date').each(
function(){
var weekday=getWeekday(parseDateTime($(this).text()));
//console.log(weekday)
if (weekday==null) weekday='';
if (weekday=='undefined,') weekday='';
$(this).prev().html(weekday);
}
);
}
// change create schedule button name (add/remove)
function updateScheduleButtonName(){
var buttonChecked=$('#schedule_add input[name="exclude"]');
if(buttonChecked.prop('checked')){
$('#addScheduleButton').text(loc['label_remove_schedule']);
}else{
$('#addScheduleButton').text(loc['label_add_schedule']);
}
}
// set css class on parent div to add margin on input fields
function setInputWidth(){
$('#content .editor div.cell input').each(function(){
$(this).parent().addClass('containsInput');
$(this).parent().removeClass('containsSelect');
});
$('#content .editor div.cell select').each(function(){
$(this).parent().addClass('containsSelect');
$(this).parent().removeClass('containsInput');
});
$('#content .editor div.cell select[name="period_type"]').each(function(){
if($(this).val()=='single'){
$(this).parent().addClass('isSingle');
$(this).addClass('isSingle');
}else{
$(this).parent().removeClass('isSingle');
$(this).removeClass('isSingle');
}
});
}
function checkExcerptField(){
var length = $('textarea[name="excerpt"]').val().length;
console.log("length="+length);
if (length > 250){
$('#excerpt_too_long').show();
}else{
$('#excerpt_too_long').hide();
}
}
function checkFields(){
checkExcerptField();
$('textarea[name="excerpt"]').on("keyup", function(){
checkExcerptField();
});
}
$(document).ready(
function(){
setupLocalization(
function(){
addBackButton();
updateWeekdays();
}
);
initRegions(region);
showDateTimePicker('input.datetimepicker.start', {
onSelect: function(){updateWeekdays();}
});
showDatePicker ('input.datetimepicker.end', {
onSelect: function(){updateWeekdays();}
});
initCheckBoxes();
addCheckBoxHandler();
$("#tabs").tabs();
$('#tabs').removeClass('ui-widget ui-widget-content ui-corner-all');
updateScheduleButtonName();
initScheduleFields();
setSelectedOptions();
//if value is not selected in a option, replace select box by input field
initSelectChangeHandler('#tabs-schedule .frequency select', 'frequency', 'frequency_days');
addSelectChangeHandler( '#tabs-schedule .frequency select', 'frequency', 'frequency_days');
initSelectChangeHandler('#tabs-schedule .duration select', 'duration', 'duration_in_minutes');
addSelectChangeHandler( '#tabs-schedule .duration select', 'duration', 'duration_in_minutes');
setInputWidth();
checkFields();
// $('#content div.cell input').change( function(){setInputWidth()});
// $('#content div.cell select').change(function(){setInputWidth()});
$('textarea').autosize();
$('table#schedule_table').tablesorter({
widgets: ["filter"],
usNumberFormat : false
});
}
);

View File

@@ -0,0 +1,233 @@
/*
show a series, its template, users and events
*/
// set checkbox values checked depending on value
function initCheckBoxes(){
$('div.editor input[type="checkbox"]').each(
function () {
if ($(this).attr('value')=='1'){
$(this).attr('value','1');
$(this).attr('checked','checked');
}else{
$(this).attr('value','0');
$(this).attr('checked',null);
}
}
);
}
// add checkbox handler to change value on click
function addCheckBoxHandler(){
$('div.editor input[type="checkbox"]').click(
function () {
if ($(this).attr('value')=='1'){
$(this).attr('value','0');
}else{
$(this).attr('value','1');
}
}
);
}
// show/hide schedule fields depending on period type for a given schedule element
function showScheduleFields(id){
var select='#'+id+' select[name="period_type"]';
var type=$(select).val();
//hide and show values for different schedule types
if (type=='single'){
$('#'+id+' div.cell.frequency').hide();
$('#'+id+' div.cell.end').hide();
$('#'+id+' div.cell.schedule_weekday').hide();
$('#'+id+' div.cell.week_of_month').hide();
$('#'+id+' div.cell.schedule_month').hide();
}else if(type=='days'){
$('#'+id+' div.cell.frequency').show();
$('#'+id+' div.cell.end').show();
$('#'+id+' div.cell.schedule_weekday').hide();
$('#'+id+' div.cell.week_of_month').hide();
$('#'+id+' div.cell.schedule_month').hide();
}else if(type=='week_of_month'){
$('#'+id+' div.cell.frequency').hide();
$('#'+id+' div.cell.end').show();
$('#'+id+' div.cell.schedule_weekday').show();
$('#'+id+' div.cell.week_of_month').show();
$('#'+id+' div.cell.schedule_month').show();
}
}
// show/hide schedule fields for all schedules
function initScheduleFields(){
$('div.row.schedule form').each(function(){
var id = $(this).attr('id');
if(contains(id,'schedule_'))showScheduleFields(id);
});
}
// preselect options in select boxes
function setSelectedOptions(){
$('div.row.schedule select').each(
function(){
var value=$(this).attr('value');
if (value==null) return;
$(this).children().each(
function(){
if ($(this).attr('value')==value){
$(this).attr('selected','selected');
}
}
);
}
);
}
function initSelectChangeHandler(selector, name, title){
$(selector).each(
function(){
//replace select by input, if no matching field
var value=$(this).attr('value');
//check if a child is selected
var found=0;
$(this).children().each(function(){
if (found==1) return;
if ($(this).attr('value')==value){
found=1;
}
});
if(found==1)return;
// find option with empty value
$(this).children().each(function(){
if ($(this).attr('value')==''){
$(this).parent().html(
loc[title]+'<br>'
+'<input name="'+name+'" value="'+value+'" class="'+name+'">'
);
}
});
setInputWidth();
}
);
}
//add handler to replace select boxes by input fields if choosen value is empty
function addSelectChangeHandler(selector, name, title){
$(selector).each(
function(){
$(this).change(function(){
if($(this).val()==''){
//replace select by input, copy value from select to input,
var value=$(this).attr('value');
$(this).parent().html(
loc[title]+'<br>'
+'<input name="'+name+'" value="'+value+'" class="'+name+'">'
);
}else{
//set selected value to select
$(this).attr('value',$(this).val());
}
setInputWidth();
});
}
);
}
// print selected weekday before datetime picker
function updateWeekdays(){
$('.schedule input.datetimepicker.start').each(
function(){
var weekday=getWeekday(parseDateTime($(this).val()));
if (weekday==null) weekday='';
if (weekday=='undefined,') weekday='';
$(this).parent().prev().html(weekday);
}
);
}
// change create schedule button name (add/remove)
function updateScheduleButtonName(){
var buttonChecked=$('#schedule_add input[name="exclude"]');
if(buttonChecked.prop('checked')){
$('#addScheduleButton').text(loc['label_remove_schedule']);
}else{
$('#addScheduleButton').text(loc['label_add_schedule']);
}
}
// set css class on parent div to add margin on input fields
function setInputWidth(){
$('#content .editor div.cell input').each(function(){
$(this).parent().addClass('containsInput');
$(this).parent().removeClass('containsSelect');
});
$('#content .editor div.cell select').each(function(){
$(this).parent().addClass('containsSelect');
$(this).parent().removeClass('containsInput');
});
$('#content .editor div.cell select[name="period_type"]').each(function(){
if($(this).val()=='single'){
$(this).parent().addClass('isSingle');
$(this).addClass('isSingle');
}else{
$(this).parent().removeClass('isSingle');
$(this).removeClass('isSingle');
}
});
}
$(document).ready(
function(){
setupLocalization(
function(){
addBackButton();
updateWeekdays();
}
);
initRegions(region);
showDateTimePicker('.datetimepicker.start', {
onSelect: function(){updateWeekdays();}
});
showDatePicker('.datetimepicker.end', {
onSelect: function(){updateWeekdays();}
});
initCheckBoxes();
addCheckBoxHandler();
$("#tabs").tabs();
$('#tabs').removeClass('ui-widget ui-widget-content ui-corner-all');
updateScheduleButtonName();
initScheduleFields();
setSelectedOptions();
//if value is not selected in a option, replace select box by input field
initSelectChangeHandler('#tabs-schedule .frequency select', 'frequency', 'frequency_days');
addSelectChangeHandler( '#tabs-schedule .frequency select', 'frequency', 'frequency_days');
initSelectChangeHandler('#tabs-schedule .duration select', 'duration', 'duration_in_minutes');
addSelectChangeHandler( '#tabs-schedule .duration select', 'duration', 'duration_in_minutes');
setInputWidth();
$('textarea').autosize();
$('table#schedule_table').tablesorter({
widgets: ["filter"],
usNumberFormat : false
});
}
);

View File

@@ -0,0 +1,27 @@
// TODO: add project_id
function edit_event(event_id, series_id, studio_id, project_id, hide_series){
var elem=$('#event_'+event_id);
if(elem.hasClass('active')){
elem.removeClass('active');
$('#event_container_'+event_id).slideToggle(
function(){
$('#event_details_'+event_id).html('');
}
);
}else{
elem.addClass('active');
var url="event.cgi?project_id="+project_id+"&studio_id="+studio_id+"&series_id="+series_id+"&event_id="+event_id+"&action=edit";
if ((hide_series!=null) && (hide_series!=''))url+='&hide_series=1';
load(url);
/*
updateContainer(
'event_details_'+event_id,
url,
function(){
$('#event_container_'+event_id).slideToggle();
}
);
*/
}
}

View File

@@ -0,0 +1,225 @@
/*
* Class: fileUploader
* Use: Upload multiple files the jQuery way
* Author: John Lanz (http://pixelcone.com)
* Version: 1.0
*/
(function($) {
$.fileUploader = {version: '1.1'};
$.fn.fileUploader = function(config){
config = $.extend({}, {
limit: '1',
imageLoader: '',
buttonUpload: '#pxUpload',
buttonClear: '#pxClear',
successOutput: 'File Uploaded',
errorOutput: 'Failed',
inputName: 'image',
inputSize: 30,
allowedExtension: 'jpg|jpeg|gif|png',
callback: function() {},
url: window.location.href
}, config);
var itr = 0; //number of files to uploaded
var $limit = 1;
//public function
$.fileUploader.change = function(e){
var fname = px.validateFile( $(e).val() );
if (fname == -1){
alert ("Invalid file!");
$(e).val("");
return false;
}
$('#px_button input').removeAttr("disabled");
var imageLoader = '';
if ($.trim(config.imageLoader) != ''){
imageLoader = '<img src="'+ config.imageLoader +'" alt="uploader" />';
}
var display = '<div class="uploadData" id="pxupload'+ itr +'_text" title="pxupload'+ itr +'">' +
'<div class="close">&nbsp;</div>' +
'<span class="fname">'+ fname +'</span>' +
'<span class="loader" style="display:none">'+ imageLoader +'</span>' +
'<div class="status"></div>'+
'</div>';
$("#px_display").append(display);
if (config.limit == '' || $limit < config.limit) {
px.appendForm();
}
$limit++;
$(e).hide();
//px.upload();
}
// To exactly match $("a.foo").live("click", fn), for example, you can write $(document).on("click", "a.foo", fn).
// $(".close").live("click", function(){
$(document).on("click", ".close", function(){
$limit--;
if ($limit == config.limit) {
px.appendForm();
}
var id = "#" + $(this).parent().attr("title");
$(id+"_frame").remove();
$(id).remove();
$(id+"_text").fadeOut("slow",function(){
$(this).remove();
});
return false;
});
//$(config.buttonClear).click(function(){
$(document).on("click", "config.buttonClear", function(){
$("#px_display").fadeOut("slow",function(){
$("#px_display").html("");
$("#pxupload_form").html("");
itr = 0;
$limit = 1;
px.appendForm();
$('#px_button input').attr("disabled","disabled");
$(this).show();
});
});
//private function
var px = {
init: function(e){
var form = $(e).parents('form');
px.formAction = $(form).attr('action');
$(form).before(' \
<div id="pxupload_form"></div> \
<div id="px_display"></div> \
<div id="px_button"></div> \
');
$(config.buttonUpload+','+config.buttonClear).appendTo('#px_button');
if ( $(e).attr('name') != '' ){
config.inputName = $(e).attr('name');
}
if ( $(e).attr('size') != '' ){
config.inputSize = $(e).attr('size');
}
$(form).hide();
$(config.buttonUpload).click(function(){
px.upload()
})
this.appendForm();
},
appendForm: function(){
itr++;
var formId = "pxupload" + itr;
var iframeId = "pxupload" + itr + "_frame";
var inputId = "pxupload" + itr + "_input";
var contents =
'<form method="post" id="'+ formId +'" action="'+ px.formAction +'" enctype="multipart/form-data" target="'+ iframeId +'">'
+'<br/>'+loc['label_name']+'<br /><input name="name" />'
+'<br/>'+loc['label_description']+'<br /><textarea name="description" rows="3" cols="40"></textarea>'
;
if (studio_id != null) contents+='<input type="hidden" name="studio_id" value="'+studio_id+'">';
if (project_id != null) contents+='<input type="hidden" name="project_id" value="'+project_id+'">';
contents+=
'<input type="file" name="'+ config.inputName +'" id="'+ inputId +'" class="pxupload" size="'+ config.inputSize +'" onchange="$.fileUploader.change(this);" />'
+'<input name="action" value="upload" type="hidden"/>'
+'</form>'
+'<iframe id="'+ iframeId +'" name="'+ iframeId +'" src="about:blank" style="display:none"></iframe>';
$("#pxupload_form").append( contents );
},
validateFile: function(file) {
if (file.indexOf('/') > -1){
file = file.substring(file.lastIndexOf('/') + 1);
}else if (file.indexOf('\\') > -1){
file = file.substring(file.lastIndexOf('\\') + 1);
}
//var extensions = /(.jpg|.jpeg|.gif|.png)$/i;
var extensions = new RegExp(config.allowedExtension + '$', 'i');
if (extensions.test(file)){
return file;
} else {
return -1;
}
},
upload: function(){
if (itr > 0){
$('#px_button input').attr("disabled","disabled");
$("#pxupload_form form").each(function(){
e = $(this);
var id = "#" + $(e).attr("id");
var input_id = id + "_input";
var input_val = $(input_id).val();
if (input_val != ""){
$(id + "_text .status").text("Uploading...");
$(id + "_text").css("background-color", "#FFF0E1");
$(id + "_text .loader").show();
$(id + "_text .close").hide();
$(id).submit();
$(id +"_frame").load(function(){
$(id + "_text .loader").hide();
up_output = $(this).contents().find("#output").html();
var success=0;
if (up_output == "success"){
success=1;
$(id + "_text").css("background-color", "#F0F8FF");
up_output = config.successOutput;
px.redirect();
}else{
$(id + "_text").css("background-color", "#FF0000");
up_output = config.errorOutput;
}
//custom code
up_output += '<br />' + $(this).contents().find("#message").html();
//alert($(this).contents())
//console.log(JSON.stringify($(this).contents()));
$(id + "_text .status").html(up_output);
if(success==1){
var image_id=$(this).contents().find("#upload_image_id").html();
var filename=$(this).contents().find("#upload_image_filename").html();
var title =$(this).contents().find("#upload_image_title").html();
var quote="'";
//remove existing image from list
$('#imageList div.images #img_'+image_id).remove();
//add image to list
$('#imageList div.images').prepend(
'<div id="img_'+image_id+'" class="image" '
+' onclick="imageAction('+quote+filename+quote+');return false;" '
+' title="'+title+'" '
+' style="background-image:url('+quote+'/agenda_files/media/thumbs/'+filename+quote+')"'
+'>'
+' <div class="label">'+title+'</div>'
+'</div>'
);
}
//end of custom code
$(e).remove();
$(config.buttonClear).removeAttr("disabled");
config.callback($(this));
});
}
});
}
},
redirect: function(){
//window.location.replace(config.url)
//$('#pxupload_form').append('<form id="redirect" method="GET" action="'+config.url+'" />');
//$('#redirect').submit();
}
}
px.init(this);
return this;
}
})(jQuery);

View File

@@ -0,0 +1,148 @@
function setCookie(name, value) {
document.cookie = name + "=" + value + "; "
}
function clearCookie(name) {
document.cookie = name + "=; "
}
function getCookie(name) {
var cookies = document.cookie.split('; ');
for(var i=0; i<cookies.length; i++) {
if (cookies[i].indexOf(name+'=')==0){
return cookies[i].substring(name.length+1);
}
}
return "";
}
function getHistory(){
var value=getCookie("history");
var history = value.split("|");
return history;
}
function comeFromCalendar(){
var history=getHistory();
if (history.length<2)return false;
if (history[1].indexOf("calendar")==-1)return false;
return true;
}
//return history or null, if url should not be appended to history
function isNewToHistory(url){
//if (window.location.search=='')return null;
/*
if (contains(url,"action")){
//action defined but not show...,edit...
if (
(!contains(url,"action=show"))
&& (!contains(url,"action=edit"))
){
//alert("return");
//return null;
}
}
*/
var params=window.location.search;
var history = getHistory();
//last page already in history
if (history[0] == url) return null;
//replace url in history by current one, if controller is the same
var urlController=url.split('.cgi').shift();
var historyController=history[0].split('.cgi').shift();
//remove last entry on same controller
if(urlController==historyController){
var ignore=0;
//provide back to series from series details
if(contains(url,'series')){
console.log(url);
console.log(history[0]);
if( (contains(url,'series_id')==true) && (contains(history[0],'series_id')==false)) ignore=1;
console.log(ignore);
}
if (ignore==0) history.shift();
}
return history;
}
// for back button add url to history, if no POST and not visited before
function appendHistory(url, rewrite){
if (url==null) url=window.location.href;
//no parameters -> propably POST?
var history=isNewToHistory(url);
if (history==null) return;
//remove first element
if(rewrite!=null)history.shift();
//limit size
if(history.length>20) history.pop();
if(history.length==0){
setCookie("history", url);
}else{
var content=url;
var i=0;
for (i in history){
if ((history[i]!=null)&&(history[i]!=''))content+='|'+history[i];
}
setCookie("history", content);
}
//showHistory();
}
function showHistory(){
var history=getHistory();
var s='<pre style="z-index:110;position:absolute;right:0;top:0">';
for (var i=5; i>=0;i--){
if(history[i]!=null) s+=i+" "+history[i]+"\n";
}
s+='</pre>';
//alert(s)
$('#content').prepend(s);
}
function getBack(){
var history=getHistory();
//alert("getBack")
if (history.length==0)return;
//remove current page
history.shift();
if (history.length==0)return;
//remove previous page
var url=history.shift();
setCookie("history", history.join("|"));
window.location.href=url;
}
// add back button if not existing
function addBackButton(){
var backButton=$('#backButton');
if(backButton.length>0)return;
if (loc['button_back']==null)return;
// add back button if history exists
var history=getHistory();
//console.log(history.length);
if (history.length>1) $('#calcms_admin_menu').first().prepend(
'<div><a id="backButton" href="#" onclick="getBack();">'
+loc['button_back']
+'</a></div>'
);
//showHistory();
}
$(document).ready(function(){
//clearCookie();
appendHistory();
});

View File

@@ -0,0 +1,202 @@
// choose action depending on selected tab
function imageAction(filename){
if(selectedImageTab=='select'){
selectThisImage(filename);
return false;
}
if(selectedImageTab=='edit'){
editImage(filename);
return false;
}
}
// get current selected tab by tabs-id
function getSelectedTab(id){
var selector='#'+id+" li.ui-tabs-active a";
var tabValue=$(selector).attr("value");
return tabValue;
}
//select image load into selectImage box
function selectImage(project_id, studio_id, id, value, imageUrl, series_id){
selectImageId=id;
value=value.replace(/[^a-zA-Z0-9]/g,'%');
var url="image.cgi?search="+encodeURIComponent(value)+'&project_id='+project_id+'&studio_id='+studio_id;
if((series_id!=null)&&(series_id != '')){
url+='&series_id='+series_id;
}
if(imageUrl!=null){
var filename=imageUrl.split('%2F').pop();
url+='&filename='+filename;
}
$('#selectImage').load(url);
$('#selectImage').dialog({
appendTo: "#content",
title:"select image",
width:"980",
height:640
});
return false;
}
// set editor image and image url to selected image
function selectThisImage(filename){
var url=('/agenda_files/media/thumbs/'+filename);
$('#'+selectImageId).val(url);
$('#imagePreview').prop('src',url);
try{
$('#selectImage').dialog('close');
}catch(e){
$('#selectImage').parent().remove();
$('html').append('<div id="selectImage"></div>');
};
return false;
}
// update selectImage container by images matching to search
function searchImage(){
var url='image.cgi?project_id='+project_id+'&studio_id='+studio_id;
var value=$('#image_manager input[name=search]').val();
value=value.replace(/[^a-zA-Z0-9]/g,'%');
if (value!=null) url+='&search='+encodeURIComponent(value)
value=$('#image_manager input[name=filename]').val();
if (value!=null) url+='&filename='+encodeURIComponent(value);
if(selectedImageTab=='edit'){
url+='#image-tabs-edit'
}
updateContainer('selectImage',url, function(){
$( "#image-tabs" ).tabs();
$( "#image-tabs" ).tabs( "option", "active", 1 );
});
//
return false;
}
// open dialog to edit image properties
function editImage(filename){
$("#img_editor").load(
'image.cgi?show='+filename+'&template=image_edit.html&project_id='+project_id+'&studio_id='+studio_id,
function(){
$('#img_editor').dialog({
appendTo: "#content",
width:"100%",
height:430
});
}
);
}
// open dialog to show image preview
function showImage(url){
$("#img_image").html('<img src="'+url+'" onclick="$(\'#img_image\').dialog(\'close\');return false;"/>');
$("#img_image").dialog({
appendTo: "#content",
width:"100%",
height:660
});
}
// save image
function saveImage(id, filename) {
var url='image.cgi?save_image='+filename+'&project_id='+project_id+'&studio_id='+studio_id;
//remove error field
if($('#image-tabs .error').length>0){
$('#image-tabs div.error').remove();
}
if (url!='') $.post(
url,
$("#save_img_"+id).serialize(),
function(data){
var lines=data.split(/\n/);
for (index in lines){
var line=lines[index];
if(contains(line,'ERROR:')){
//add error field
if($('#image-tabs .error').length==0){
$('#image-tabs').append('<div class="error"></div>');
}
$('#image-tabs div.error').append(line);
}
};
//console.log(data);
console.log("save "+id);
hideImageDetails('img_'+id, filename);
}
);
return false;
}
// delete image
function askDeleteImage(id, filename) {
commitAction("delete image", function(){ deleteImage(id, filename) } );
}
// delete image
function deleteImage(id, filename) {
//alert("deleteImage");return;
$("#"+id).load('image.cgi?delete_image='+filename+'&project_id='+project_id+'&studio_id='+studio_id);
hideImageDetails('img_'+id, filename);
$("#"+id).hide('drop');
return false;
}
// close all open dialogs
function hideImageDetails(id,filename){
try{$('#img_editor').dialog('close');}catch(e){}
try{$('#img_image').dialog("close");}catch(e){}
$("#"+id).load('image.cgi?show='+filename+'&template=image_single.html&project_id='+project_id+'&studio_id='+studio_id);
return false;
}
// show image url
function showImageUrl(id){
var el=document.getElementById(id);
var input_id=id+'_input';
var text='<input id="'+input_id+'" value="{{thumbs/'+id+'|title}}" title="3fach-Klick zum Markieren!">';
if (el.innerHTML==text){
el.innerHTML='';
}else{
el.innerHTML=text;
var input=document.getElementById(input_id);
input.focus();
input.select();
input.createTextRange().execCommand("Copy");
}
return false;
}
// zoom all images in
function increaseImageSize(){
var value=$('#content div.image').css('width');
value=value.replace(/[^0-9]/g,'');
if(value>200)return;
value=parseInt(value*1.3);
$('#content div.image').css('width', value+'px');
$('#content div.image div').css('width', (value-12)+'px');
$('#content div.image').css('height', value+'px');
$('#content div.image').css('background-size', value+'px');
}
// zoom all images out
function decreaseImageSize(){
var value=$('#content div.image').css('width');
value=value.replace(/[^0-9]/g,'');
if(value<50)return;
value=parseInt(value/1.3);
$('#content div.image').css('width', value+'px');
$('#content div.image div').css('width', (value-12)+'px');
$('#content div.image').css('height', value+'px');
$('#content div.image').css('background-size', value+'px');
}

View File

@@ -0,0 +1,67 @@
// init upload
function initUploadDialog(){
//console.log("init upload dialog")
if(!$('#uploader').hasClass("init")){
$('#uploader').fileUploader();
$('#uploader').addClass("init");
//remove multiple buttons
var c=0;
$('#img_upload #px_button').each(
function(){
if (c>0){
$(this).remove();
}
c++;
}
);
}
return false;
}
// prepare for new init
function closeImageUpload(){
$('#uploader').removeClass("init");
$('#pxupload_form').remove();
$('#pxupload1_frame').remove();
$('#px_display').remove();
}
function insertPicture(name, description, filename) {
try {
markup='{{ thumbs//'+filename;
if (description !=''){
markup+=' | '+description;
}else{
if (name !='') markup+=' | '+name
}
markup+=' }}'
markup+="\n"
parent.$.markItUp( { replaceWith:markup } );
parent.$('#images').dialog("close");
} catch(e) {
alert("No markItUp! Editor found");
}
}
function image_upload_dialog(){
$('#img_upload').dialog({
title:"image upload",
width:600,
height:320
});
return false;
}
function image_upload_callback(result){
result.contents().find("#message").html();
var output = '<br />' + $(this).contents().find("#message").html();
$(id + "_text .status").html(output);
}
$(document).ready(
function() {
//$('#uploader').fileUploader();
}
)

File diff suppressed because one or more lines are too long

16617
website/agenda/planung/js/jquery-ui.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

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