first commit
This commit is contained in:
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/.vscode/
|
||||
*/.vscode/
|
||||
/.theia/
|
||||
*/.theia/
|
||||
*/*.deb
|
||||
*.deb
|
||||
131
createapp.pl
Normal file
131
createapp.pl
Normal file
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Data::Printer;
|
||||
use File::Find;
|
||||
use File::Copy;
|
||||
use Cwd;
|
||||
use File::Slurp;
|
||||
|
||||
my $secret = `openssl rand -base64 48`;
|
||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
|
||||
$year = $year+1900;
|
||||
|
||||
chomp $secret;
|
||||
|
||||
my $rc = system('git --version');
|
||||
if ( $rc < 0) {
|
||||
print STDOUT "GIT scheint nicht installiert zu sein, Programm wird geschlossen\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
print "Wie soll das neue Programm heißen: ";
|
||||
chomp( my $name = <ARGV> );
|
||||
|
||||
if ( $name !~ /^[a-z]*$/ ) {
|
||||
print STDOUT "Programmname muss existieren und darf nur kleinbuchstaben beinhalten, Programm wird geschlossen\n";
|
||||
exit 0;
|
||||
} elsif ( $name eq 'xxx' ) {
|
||||
print STDOUT "Programmname darf nicht xxx heißen, Programm wird geschlossen\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
print "Wohin soll das neue Programm kopiert werden ( $ENV{'HOME'}/mojo ): ";
|
||||
chomp( my $wohin = <ARGV> );
|
||||
|
||||
if ( $wohin eq "" ) {
|
||||
$wohin = "$ENV{'HOME'}/mojo";
|
||||
};
|
||||
if ( !-d $wohin ) {
|
||||
print STDOUT "Ordner existiert nicht, Programm wird geschlossen\n";
|
||||
exit 0;
|
||||
} elsif ( $wohin =~ /create_mojo_app/ ) {
|
||||
print STDOUT "Ordner mit create_mojo_app im Namen sind nicht erlaubt, Programm wird geschlossen\n";
|
||||
exit 0;
|
||||
} elsif ( !-w $wohin ) {
|
||||
print STDOUT "in Ordner $wohin kann nicht geschrieben werden, Programm wird geschlossen\n";
|
||||
exit 0;
|
||||
} else {
|
||||
|
||||
}
|
||||
$wohin = $wohin =~ s/\/*$//r; # letztes / entfernen
|
||||
|
||||
my $lname = lcfirst $name;
|
||||
my $uname = ucfirst $name;
|
||||
|
||||
print "Wofür ist $lname: ";
|
||||
chomp( my $wofuer = <ARGV> );
|
||||
|
||||
print "auf welchem Port soll $uname laufen (Default 3000): ";
|
||||
chomp( my $port = <ARGV> );
|
||||
if ( $port eq "" ) { $port = 3000 }
|
||||
|
||||
my $dir = getcwd;
|
||||
|
||||
# Ordner und Dateinamen in xxx durchgehen und XXX mit neuen Appnamen ersetzen
|
||||
find( \&files, 'xxx' );
|
||||
|
||||
sub files {
|
||||
my $str = $File::Find::name;
|
||||
$str =~ s/Xxx/$uname/g;
|
||||
$str =~ s/xxx/$lname/g;
|
||||
|
||||
if (-d) {
|
||||
mkdir $wohin . '/' . $str;
|
||||
}
|
||||
else {
|
||||
copy( $dir . '/' . $File::Find::name, $wohin . '/' . $str )
|
||||
or die "The move operation failed: $!";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
# Dateien in neuen Appordner durchgehen und Werte mit neuen ersetzen
|
||||
find( \&newfiles, "$wohin/$lname" );
|
||||
|
||||
sub newfiles {
|
||||
|
||||
if (-f) {
|
||||
|
||||
#print "File: $dir/$File::Find::name\n";
|
||||
if ( $File::Find::name !~ m/.png/g ) {
|
||||
my @lines = read_file($File::Find::name);
|
||||
write_file($File::Find::name, '');
|
||||
|
||||
for my $line (@lines) {
|
||||
$line =~ s/mojocreateyear/$year/g;
|
||||
$line =~ s/Xxx/$uname/g;
|
||||
$line =~ s/xxx/$lname/g;
|
||||
$line =~ s/mojoappsecret/$secret/g;
|
||||
$line =~ s/hypnotoadport/$port/g;
|
||||
$line =~ s/wofuer/$wofuer/g;
|
||||
append_file($File::Find::name, $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
# Rechte der Datei ändern
|
||||
|
||||
chmod( 0755, "$wohin/$lname/app/morbo.sh" );
|
||||
chmod( 0755, "$wohin/$lname/app/test.sh" );
|
||||
chmod( 0755, "$wohin/$lname/deb/DEBIAN/postinst" );
|
||||
chmod( 0755, "$wohin/$lname/deb/DEBIAN/prerm" );
|
||||
chmod( 0755, "$wohin/$lname/deb/pbuild.sh" );
|
||||
|
||||
print "App: $uname erstellt\n";
|
||||
chdir "$wohin/$lname/";
|
||||
system( "git init" );
|
||||
system( "git add ." );
|
||||
system( "git commit -m 'initialer Commit'" );
|
||||
system( "git remote add origin git\@git:WebApps/$uname.git" );
|
||||
|
||||
system( "$wohin/$lname/deb/pbuild.sh" ) == 0
|
||||
or die "Bash Script failed";
|
||||
1;
|
||||
|
||||
system( "$wohin/$lname/app/morbo.sh" ) == 0
|
||||
or die "Bash Script failed";
|
||||
1;
|
||||
116
xxx/app/lib/XxxApp.pm
Normal file
116
xxx/app/lib/XxxApp.pm
Normal file
@@ -0,0 +1,116 @@
|
||||
package XxxApp;
|
||||
use Mojo::Base 'Mojolicious';
|
||||
use Time::localtime;
|
||||
|
||||
# This method will run once at server start
|
||||
sub startup {
|
||||
my $self = shift;
|
||||
|
||||
# einlesen der lokalen Config
|
||||
my $config = $self->plugin('Config');
|
||||
# $self->plugin('Config', 'file' => $config->{zus_config}); # hier und in der konfig zus_config aktivieren
|
||||
|
||||
$self->secrets([ $config->{secret}]);
|
||||
|
||||
$config->{version} = '__VERSION__';
|
||||
$config->{prefix} = '';
|
||||
|
||||
# Logging mit Log4perl
|
||||
$self->plugin('steffen::MojoPlug::Syslog' => $config->{logging} );
|
||||
$self->app->log->info(sprintf('%s v%s (Perl %s, Mojolicious v%s) started', 'Xxx', $config->{version}, $^V, $Mojolicious::VERSION));
|
||||
|
||||
# Authentication & Authorization
|
||||
$self->sessions->cookie_name('Xxx');
|
||||
$self->sessions->default_expiration(3600);
|
||||
$self->sessions->samesite('Strict');
|
||||
delete $self->app->static->extra->{'favicon.ico'};
|
||||
push @{$self->app->static->paths}, $config->{htlib};
|
||||
|
||||
# Kompression
|
||||
$self->app->renderer->compress(1);
|
||||
|
||||
# Authorisation
|
||||
$self->plugin('steffen::MojoPlug::Authorization' => { verbose => 1 });
|
||||
|
||||
# Menu über config
|
||||
$self->plugin('Config', file => 'navigation.conf');
|
||||
$self->plugin('steffen::MojoPlug::NavHelper' => { verbose => 1, bs => 5 });
|
||||
|
||||
# deaktivierte Plugins
|
||||
# $self->plugin('RenderFile');
|
||||
# mysql
|
||||
# $self->plugin('steffen::MojoPlug::Mysql' => { db => $config->{db} });
|
||||
# $config->{test} = $self->dbxxx->{dsn} =~ m/dbs-test/gxms;
|
||||
|
||||
# Local Helpers
|
||||
$self->plugin('XxxApp::Helpers' => { verbose => 1 });
|
||||
|
||||
# https://editor.swagger.io/?url=https://petstore.swagger.io/v2/swagger.yaml
|
||||
$self->plugin('OpenAPI' => {
|
||||
#route => $self->app->routes->under("/api")->to("api#auth"),
|
||||
url => $self->app->home->rel_file("openapi.json"),
|
||||
schema => 'v3',
|
||||
security => {
|
||||
BasicAuth => sub {
|
||||
my ($c, $definition, $scopes, $cb) = @_;
|
||||
my $haspriv;
|
||||
for my $sc ( @{$scopes} ) {
|
||||
$haspriv = 1 if $c->has_priv($sc);
|
||||
}
|
||||
|
||||
if ( $haspriv ) {
|
||||
return $c->$cb()
|
||||
} else {
|
||||
return $c->$cb('no permission')
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$self->plugin( 'steffen::MojoPlug::SwaggerUI' => {
|
||||
route => $self->app->routes()->any('/rfc'),
|
||||
url => "/api",
|
||||
title => "Xxx",
|
||||
favicon => "/images/favicon.png"
|
||||
}
|
||||
);
|
||||
|
||||
$self->hook(
|
||||
'before_dispatch' => sub {
|
||||
my $c = shift;
|
||||
$c->req->url->base->path('');
|
||||
$config->{prefix} = '';
|
||||
if (!!$c->req->headers->header('Mojo-RP-Location')) {
|
||||
$c->req->url->base->path( $c->req->headers->header('Mojo-RP-Location') );
|
||||
$config->{prefix} = '/'.$c->req->headers->header('Mojo-RP-Location');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
# Hook für CORS
|
||||
$self->hook(
|
||||
'after_dispatch' => sub {
|
||||
my $c = shift;
|
||||
$c->res->headers->header('Access-Control-Allow-Origin' => '*');
|
||||
$c->res->headers->remove('Server');
|
||||
}
|
||||
);
|
||||
|
||||
# Router
|
||||
my $r = $self->routes;
|
||||
|
||||
# Normal route to controller
|
||||
$r->get('/') ->to('main#main', title => 'Xxx');
|
||||
$r->get('/jstreetemplate') ->to('menu#jstreetemplate', title => 'JStree Template'); # Beispiel kann gelöscht werden
|
||||
|
||||
$r->get('/xxx') ->to('main#xxx', title => 'Xxx');
|
||||
$r->get('/about') ->to('main#about', title => 'Über Xxx');
|
||||
$r->get('/login') ->to('main#loginform');
|
||||
$r->post('/login') ->to('main#login');
|
||||
$r->get('/userinfo') ->to('main#userinfo');
|
||||
$r->get('/getoff') ->to('main#getoff');
|
||||
|
||||
# API über OpenAPI Plugin
|
||||
}
|
||||
|
||||
1;
|
||||
376
xxx/app/lib/XxxApp/Controller/Api/Jstreetemplate.pm
Normal file
376
xxx/app/lib/XxxApp/Controller/Api/Jstreetemplate.pm
Normal file
@@ -0,0 +1,376 @@
|
||||
package XxxApp::Controller::Api::Jstreetemplate;
|
||||
use Mojo::Base 'Mojolicious::Controller';
|
||||
use Data::Printer;
|
||||
|
||||
my @liste = qw|Anstand
|
||||
Aufmerksamkeit
|
||||
Auftrieb
|
||||
Ausgelassenheit
|
||||
Ausgewogenheit
|
||||
Auszeichnung
|
||||
Bedeutung
|
||||
Begeisterung
|
||||
Beglückung
|
||||
Behaglichkeit
|
||||
Beherztheit
|
||||
Belohnung
|
||||
Bereicherung
|
||||
Bewunderung
|
||||
Chance
|
||||
Charisma
|
||||
Charme
|
||||
Dankbarkeit
|
||||
Daseinsfreude
|
||||
Ehrlichkeit
|
||||
Einfallsreichtum
|
||||
Einigkeit
|
||||
Empfehlung
|
||||
Energie
|
||||
Engagement
|
||||
Entspannung
|
||||
Erfolg
|
||||
Erfüllung
|
||||
Ermutigung
|
||||
Faszination
|
||||
Freiheit
|
||||
Freude
|
||||
Freunde
|
||||
Freundlichkeit
|
||||
Fröhlichkeit
|
||||
Fülle
|
||||
Füreinandereintreten
|
||||
Gabe
|
||||
Geduld
|
||||
Gegenseitigkeit
|
||||
Gemeinschaftsgeist
|
||||
Geschenk
|
||||
Geschlossenheit
|
||||
Gesundheit
|
||||
Glück
|
||||
Glückseligkeit
|
||||
Glückwunsch
|
||||
Großzügigkeit
|
||||
Güte
|
||||
Harmonie
|
||||
Hauptgewinn
|
||||
Heiterkeit
|
||||
Herzenswärme
|
||||
Herzensgüte
|
||||
Herzlichkeit
|
||||
Hilfsbereitschaft
|
||||
Hinwendung
|
||||
Hochgefühl
|
||||
Hoffnung
|
||||
Höflichkeit
|
||||
Idealismus
|
||||
Intuition
|
||||
Ideenreichtum
|
||||
Idylle
|
||||
Inspiration
|
||||
Interesse
|
||||
Jubel
|
||||
Jugendlichkeit
|
||||
Kompliment
|
||||
Köstlichkeit
|
||||
Kraft
|
||||
Kreativität
|
||||
Lächeln
|
||||
Lachen
|
||||
Leben
|
||||
Lebenslust
|
||||
Lebendigkeit
|
||||
Lebensfreude
|
||||
Lebhaftigkeit
|
||||
Leichtigkeit
|
||||
Leidenschaft
|
||||
Liebe
|
||||
Liebenswürdigkeit
|
||||
Luxus
|
||||
Munterkeit
|
||||
Mut
|
||||
Nähe
|
||||
Offenheit
|
||||
Optimismus
|
||||
Originalität
|
||||
Pracht
|
||||
Prestige
|
||||
Problemlösung
|
||||
Pünktlichkeit
|
||||
Reichhaltigkeit
|
||||
Reichtum
|
||||
Respekt
|
||||
Richtigkeit
|
||||
Rücksicht
|
||||
Rücksichtnahme
|
||||
Schönheit
|
||||
Schutz
|
||||
Seelenverwandtschaft
|
||||
Selbstachtung
|
||||
Selbstbestimmung
|
||||
Selbstliebe
|
||||
Selbstlosigkeit
|
||||
Selbstsicherheit
|
||||
Selbstwertgefühl
|
||||
Selbstzufriedenheit
|
||||
Seligkeit
|
||||
Sicherheit
|
||||
Solidarität
|
||||
Sorgfalt
|
||||
Spaß
|
||||
Spontanität
|
||||
Stärke
|
||||
Sympathie
|
||||
Toleranz
|
||||
Treue
|
||||
Überfluss
|
||||
Überraschung
|
||||
Überschwang
|
||||
Überzeugung
|
||||
Überzeugungskraft
|
||||
Unbeschwertheit
|
||||
Unterstützung
|
||||
Verbesserung
|
||||
Verbundenheit
|
||||
Verehrung
|
||||
Verlockung
|
||||
Verspieltheit
|
||||
Verständnis
|
||||
Vertrauen
|
||||
Vertrauenswürdigkeit
|
||||
Vertrautheit
|
||||
Vertraulichkeit
|
||||
Vielfalt
|
||||
Vielseitigkeit
|
||||
Wahrhaftigkeit
|
||||
Wärme
|
||||
Willenskraft
|
||||
Willkommen
|
||||
Wohlbefinden
|
||||
Wohlgefallen
|
||||
Wohlstand
|
||||
Wohltat
|
||||
Wonne
|
||||
Würde
|
||||
Wunder
|
||||
Zauber
|
||||
Zufriedenheit
|
||||
Zuneigung
|
||||
Zusammengehörigkeit
|
||||
Zusammenhalt
|
||||
Zuverlässigkeit
|
||||
Zuwendung|;
|
||||
|
||||
sub jstreedata {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
my ($src, $tab ) = _generatetestdata();
|
||||
|
||||
my @tree;
|
||||
push @tree, @{$src};
|
||||
push @tree, @{$tab};
|
||||
|
||||
return $c->render(json => { rc => 0, msg => 'OK', data => \@tree} );
|
||||
}
|
||||
|
||||
sub _generatetestdata {
|
||||
my ( $liste ) = @_;
|
||||
my $src;
|
||||
my $tab;
|
||||
my $cnt = @liste;
|
||||
|
||||
my $first = int(rand( 10));
|
||||
$first ++;
|
||||
my $second = int(rand( 10));
|
||||
$second ++;
|
||||
my $third = int(rand( 10));
|
||||
$third ++;
|
||||
|
||||
for my $f ( 1..$first ) {
|
||||
my $word = int(rand( $cnt ));
|
||||
push @{$src}, { parent => '#', id => $f, text => $liste[$word] };
|
||||
|
||||
for my $s ( 1..$second ) {
|
||||
my $fs = $f * 10 + $s;
|
||||
my $wordchild = int(rand( $cnt ));
|
||||
push @{$tab}, { parent => $f, id => $fs, text => $liste[$wordchild] };
|
||||
|
||||
for my $t ( 1..$third ) {
|
||||
my $fst = $fs * 10 + $t;
|
||||
my $wordchild2 = int(rand( $cnt ));
|
||||
push @{$tab}, { parent => $fs, id => $fst, text => $liste[$wordchild2] },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ($src, $tab );
|
||||
}
|
||||
|
||||
sub datatablesdata {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
my $cnt = @liste;
|
||||
|
||||
my $rows = int(rand( 1000));
|
||||
$rows ++;
|
||||
my @data;
|
||||
|
||||
for my $d ( 0..$rows ) {
|
||||
my $col1 = int(rand( $cnt ));
|
||||
my $col2 = int(rand( $cnt ));
|
||||
my $col3 = int(rand( $cnt ));
|
||||
my $col4 = int(rand( $cnt ));
|
||||
my $col5 = int(rand( $cnt ));
|
||||
my $col6 = int(rand( $cnt ));
|
||||
my $col7 = int(rand( $cnt ));
|
||||
my $col8 = int(rand( $cnt ));
|
||||
my $col9 = int(rand( $cnt ));
|
||||
|
||||
push @data, { col1 => $liste[$col1], col2 => $liste[$col2], col3 => $liste[$col3], col4 => $liste[$col4], col5 => $liste[$col5], col6 => $liste[$col6], col7 => $liste[$col7], col8 => $liste[$col8], col9 => $liste[$col9] };
|
||||
}
|
||||
|
||||
|
||||
return $c->render(json => { rc => 0, msg => 'OK', data => \@data} );
|
||||
}
|
||||
|
||||
|
||||
###
|
||||
sub listfiles {
|
||||
my $self = shift;
|
||||
|
||||
my $id = $self->stash('todoid');
|
||||
|
||||
my $sql = "SELECT idma,
|
||||
size,
|
||||
created,
|
||||
info,
|
||||
type,
|
||||
name
|
||||
FROM todo_master_files
|
||||
WHERE id = ? and deleted = 0";
|
||||
|
||||
my ( $rc, $msg, $data ) = $self->dbxxx->query_hash_array( $sql, $id );
|
||||
|
||||
return $self->render( json => { rc => $rc, msg => $msg, data => $data} );
|
||||
}
|
||||
|
||||
|
||||
sub blob {
|
||||
my $self = shift;
|
||||
|
||||
my $dbh = $self->dbxxx->get;
|
||||
return (1, "kein DB-Handle bekommen") if !defined $dbh;
|
||||
|
||||
my $cursor = $dbh->prepare("SELECT file, type FROM todo_master_files where idma = ?");
|
||||
$cursor->execute($self->stash('idma'));
|
||||
my @data = $cursor->fetchrow;
|
||||
$cursor->finish;
|
||||
|
||||
my $blob;
|
||||
|
||||
if ( defined $data[0]) {
|
||||
$blob = encode_base64($data[0]);
|
||||
} else {
|
||||
$blob = '';
|
||||
}
|
||||
|
||||
$self->dbxxx->free($dbh);
|
||||
return $self->render( json => { blob => $blob, type => $data[1] });
|
||||
}
|
||||
|
||||
|
||||
sub update {
|
||||
# update eines eintrages der Mastertabelle
|
||||
my $self = shift;
|
||||
|
||||
my $todoid = $self->stash('todoid');
|
||||
return $self->render( json => { rc => 1, msg => "Die todoid fehlt"} ) if ( $todoid eq "" ) ;
|
||||
|
||||
my $daten = $self->req->json;
|
||||
|
||||
return $self->render( json => { rc => 1, msg => 'Programmname fehlt'} ) if ( !defined $daten->{name} or $daten->{name} eq "" );
|
||||
return $self->render( json => { rc => 1, msg => 'Verantwortlichkeit zuweisen'} ) if ( !defined $daten->{who} or $daten->{who} eq "" );
|
||||
return $self->render( json => { rc => 1, msg => 'Prozesszuweisung fehlt'} ) if ( !defined $daten->{prozess} or $daten->{prozess} eq "" );
|
||||
return $self->render( json => { rc => 1, msg => 'Festellung definieren'} ) if ( !defined $daten->{todoinfo} or $daten->{todoinfo} eq "" );
|
||||
return $self->render( json => { rc => 1, msg => 'ext fehlt'} ) if ( !defined $daten->{ext} );
|
||||
|
||||
my $sql = "UPDATE todo_master set
|
||||
name = ?,
|
||||
who = ?,
|
||||
prozess = ?,
|
||||
todoinfo = ?,
|
||||
status = ?,
|
||||
finishdate = ?,
|
||||
closed = ?,
|
||||
notes_master = ?,
|
||||
targetdate_master = ?,
|
||||
ext = ?
|
||||
WHERE id = ?";
|
||||
|
||||
my ($rc, $msg ) = $self->dbxxx->query_res( $sql, $daten->{'name'},
|
||||
$daten->{'who'},
|
||||
$daten->{'prozess'},
|
||||
$daten->{'todoinfo'},
|
||||
$daten->{'status'},
|
||||
$daten->{'finishdate'},
|
||||
$daten->{'closed'},
|
||||
$daten->{'notes_master'},
|
||||
$daten->{'targetdate_master'},
|
||||
$daten->{'ext'},
|
||||
$todoid);
|
||||
return $self->render(json => { rc => $rc, msg => $msg });
|
||||
}
|
||||
|
||||
|
||||
sub insert_file {
|
||||
my $self = shift;
|
||||
|
||||
my $file = $self->param("file");
|
||||
my $todoid = $self->param("id");
|
||||
my $info = $self->param("info");
|
||||
|
||||
return $self->render(json => { rc => 1, msg => "Die todoid fehlt"} ) if ( $todoid eq "" ) ;
|
||||
return $self->render(json => { rc => 1, msg => "Die Info fehlt"} ) if ( $info eq "" ) ;
|
||||
return $self->render(json => { rc => 1, msg => 'file'}) if (!defined $file->asset->slurp or $file->asset->slurp eq "");
|
||||
return $self->render(json => { rc => 1, msg => 'name'}) if (!defined $file->filename or $file->filename eq "");
|
||||
return $self->render(json => { rc => 1, msg => 'type'}) if (!defined $file->headers->content_type or $file->headers->content_type eq "");
|
||||
return $self->render(json => { rc => 1, msg => 'size'}) if (!defined $file->size or $file->size eq "");
|
||||
|
||||
my $sql = "INSERT INTO todo_master_files (id, file, type, name, size, info) VALUES (?,?,?,?,?,?)";
|
||||
|
||||
my ($rc, $msg ) = $self->dbxxx->query_res( $sql, $todoid, $file->asset->slurp, $file->headers->content_type, $file->filename, $file->size, $info );
|
||||
|
||||
return $self->render(template => 'main/todo_main');
|
||||
}
|
||||
|
||||
|
||||
sub insert_datei {
|
||||
my $self = shift;
|
||||
|
||||
my $daten = $self->req->json;
|
||||
my $id = $self->stash("todoid");
|
||||
|
||||
return $self->render(json => { rc => 1, msg => "Die ID fehlt"} ) if ( $id eq "" ) ;
|
||||
my $filebase64 = $daten->{file};
|
||||
$filebase64 =~ s/data:$daten->{type};base64//;
|
||||
|
||||
my $file = decode_base64($filebase64);
|
||||
|
||||
my $sql = "INSERT INTO todo_master_files (id, file, type, name, size, info) VALUES (?,?,?,?,?,?)";
|
||||
|
||||
my ($rc, $msg ) = $self->dbxxx->query_res( $sql, $id, $file, $daten->{type}, $daten->{name}, $daten->{size}, $daten->{info});
|
||||
# oder mit der zurückgegebenen id
|
||||
# my ($rc, $msg, $insid ) = $self->dbkoma->query_inserted_id( $sql, $id, $file, $daten->{type}, $daten->{name}, $daten->{size}, $daten->{info});
|
||||
|
||||
return $self->render(json => { rc => $rc, msg => $msg });
|
||||
}
|
||||
|
||||
|
||||
sub deletefile {
|
||||
my $self = shift;
|
||||
my $id = $self->stash('idma');
|
||||
return $self->render(json => { rc => 1, msg => "Die idma fehlt"}) if ( $id eq "" ) ;
|
||||
|
||||
my ($rc, $msg) = $self->dbxxx->query_res( "DELETE FROM todo_master_files WHERE idma = ?", $id);
|
||||
return $self->render( json => { rc => $rc, msg => $msg });
|
||||
}
|
||||
|
||||
1;
|
||||
10
xxx/app/lib/XxxApp/Controller/Menu.pm
Normal file
10
xxx/app/lib/XxxApp/Controller/Menu.pm
Normal file
@@ -0,0 +1,10 @@
|
||||
package XxxApp::Controller::Menu;
|
||||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
sub jstreetemplate {
|
||||
my $c = shift;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
||||
30
xxx/app/lib/XxxApp/Helpers.pm
Normal file
30
xxx/app/lib/XxxApp/Helpers.pm
Normal file
@@ -0,0 +1,30 @@
|
||||
package XxxApp::Helpers;
|
||||
use Mojo::Base 'Mojolicious::Plugin';
|
||||
|
||||
sub register {
|
||||
my ($self, $app, $args) = @_;
|
||||
|
||||
$app->helper('trim' => \&_trim);
|
||||
$app->helper('debuglog' => \&_debuglog);
|
||||
|
||||
$app->log->info(sprintf('REGISTERED: %s', __PACKAGE__)) if !!$args->{verbose};
|
||||
return;
|
||||
}
|
||||
|
||||
# Führende und nachfolgende Leerzeichen entfernen
|
||||
sub _trim {
|
||||
my ($c, $str) = @_;
|
||||
$str =~ s/^\s+|\s+$//g;
|
||||
return $str;
|
||||
};
|
||||
|
||||
sub _debuglog {
|
||||
my ($c, $info) = @_;
|
||||
if ( $c->config->{logging}->{level} =~ /trace|debug/ ) {
|
||||
$c->log->debug($info);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
53
xxx/app/lib/XxxApp/Main.pm
Normal file
53
xxx/app/lib/XxxApp/Main.pm
Normal file
@@ -0,0 +1,53 @@
|
||||
package XxxApp::Main;
|
||||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
sub main {
|
||||
my $self = shift;
|
||||
return $self->render( template => 'main/main', title => 'Xxx', msg => '' );
|
||||
}
|
||||
|
||||
|
||||
sub login {
|
||||
my $self = shift;
|
||||
|
||||
# Grab the request parameters
|
||||
my $username = $self->param('username');
|
||||
my $password = $self->param('password');
|
||||
|
||||
my $developer = ($username eq 'developer' and $password eq 'wbdfgmnjke834dshf89w7rsdfsdjf' and $self->app->mode =~ /development/xms ) ? 1 : 0;
|
||||
|
||||
if ( $developer or $self->authenticate( $username, $password )) {
|
||||
$self->session->{msg} = 'Login erfolgreich!';
|
||||
push @{$self->session->{privs}}, 'user';
|
||||
} else {
|
||||
$self->logoff();
|
||||
$self->session->{url} = '/login';
|
||||
$self->session->{msg} = 'Fehler, das Login wurde abgewiesen!';
|
||||
}
|
||||
|
||||
return $self->redirect_to( defined $self->session->{url} ? $self->session->{url} : "/" );
|
||||
}
|
||||
|
||||
sub loginform {
|
||||
my $self = shift;
|
||||
return $self->render( title => 'xxx: Main', msg => '', sess => $self->session);
|
||||
}
|
||||
|
||||
|
||||
sub userinfo {
|
||||
my $self = shift;
|
||||
return $self->render( title => 'xxx: Userinfo', sess => $self->session, msg => 'Du besitzt folgende Rechte:');
|
||||
}
|
||||
|
||||
|
||||
sub getoff {
|
||||
my $self = shift;
|
||||
$self->logoff();
|
||||
delete $self->session->{privs};
|
||||
$self->session->{url} = '/';
|
||||
$self->session->{msg} = 'bye, bye ...';
|
||||
return $self->redirect_to( "/");
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
4
xxx/app/morbo.sh
Normal file
4
xxx/app/morbo.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd "${0%/*}"
|
||||
morbo -l http://*:hypnotoadport script/XxxApp -w templates -w lib -w *.conf -w *.json
|
||||
39
xxx/app/navigation.conf
Normal file
39
xxx/app/navigation.conf
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
navigation => {
|
||||
menu => [
|
||||
# {
|
||||
# text => 'QS',
|
||||
# dropdown => [
|
||||
# { text => 'Arbeitsvorrat', href => '/rech/qs' },
|
||||
# ]
|
||||
# },
|
||||
# {
|
||||
# text => 'Recherchen',
|
||||
# dropdown => [
|
||||
# { text => 'Was steht zum Transport bereit?', href => '/rech/dropd' },
|
||||
# { text => 'Was wird gerade transportiert?', href => '/rech/taken' },
|
||||
# { text => 'Was wurde bereits transportiert?', href => '/rech/done' },
|
||||
# ]
|
||||
# },
|
||||
# {
|
||||
# text => 'Auswertungen',
|
||||
# dropdown => [
|
||||
# { text => 'Transportstatistik', href => '/rept/statistik/0' },
|
||||
# { text => 'QS-Statistik', href => '/rept/statistik/1' },
|
||||
# ]
|
||||
# },
|
||||
# {
|
||||
# text => 'Konfiguration',
|
||||
# priv => 'admin',
|
||||
# dropdown => [
|
||||
# { text => 'Standort festlegen', href => '/conf/stdort' },
|
||||
# ]
|
||||
# },
|
||||
{
|
||||
priv => 'user',
|
||||
text => 'JSTree Template',
|
||||
href => '/jstreetemplate',
|
||||
},
|
||||
],
|
||||
}
|
||||
};
|
||||
209
xxx/app/openapi.json
Normal file
209
xxx/app/openapi.json
Normal file
@@ -0,0 +1,209 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"servers": [
|
||||
{
|
||||
"url": "/api"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"version": "1.0",
|
||||
"title": "Steffens Xxx API"
|
||||
},
|
||||
"paths": {
|
||||
"/jstreedata": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BasicAuth": [
|
||||
"user"
|
||||
]
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"Jstreetemplate"
|
||||
],
|
||||
"operationId": "jstreedata",
|
||||
"x-mojo-name": "jstreetemplate_jstreedata",
|
||||
"x-mojo-to": "api-jstreetemplate#jstreedata",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Daten für das JSTree",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/mls_default_response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jstreedataupdate": {
|
||||
"post": {
|
||||
"summary": "nicht funktionierende UPDATE Route Controller existiert nicht",
|
||||
"security": [
|
||||
{
|
||||
"BasicAuth": [
|
||||
"user"
|
||||
]
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"Jstreetemplate"
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "ident zum update",
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"kat_id": {
|
||||
"description": "Kategorie ident zum update",
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"name": {
|
||||
"description": "Name der Kategorie",
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"operationId": "jstreedataupdate",
|
||||
"x-mojo-name": "jstreetemplate_jstreedataupdate",
|
||||
"x-mojo-to": "api-jstreetemplate#jstreedataupdate",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Daten für das JSTree",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/mls_default_response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/jstree/{id}/{kat_id}": {
|
||||
"get": {
|
||||
"summary": "nicht funktionierende GET Path Route Controller existiert nicht",
|
||||
"security": [
|
||||
{
|
||||
"BasicAuth": [
|
||||
"user"
|
||||
]
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"Jstreetemplate"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"required": true,
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"name": "kat_id",
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"operationId": "jstree",
|
||||
"x-mojo-name": "jstreetemplate_jstree",
|
||||
"x-mojo-to": "api-jstreetemplate#jstree",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Daten für das JSTree",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/mls_default_response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/datatablesdata": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BasicAuth": [
|
||||
"user"
|
||||
]
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"Jstreetemplate"
|
||||
],
|
||||
"operationId": "datatablesdata",
|
||||
"x-mojo-name": "jstreetemplate_datatablesdata",
|
||||
"x-mojo-to": "api-jstreetemplate#datatablesdata",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Daten für die Tabelle",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/mls_default_response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"securitySchemes": {
|
||||
"BasicAuth": {
|
||||
"type": "http",
|
||||
"scheme": "basic"
|
||||
}
|
||||
},
|
||||
"schemas": {
|
||||
"mls_default_response": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"rc": {
|
||||
"type": "integer",
|
||||
"enum": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"description": "0 - alles gut | 1 - Fehler"
|
||||
},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
34
xxx/app/public/css/jstreetemplate.css
Normal file
34
xxx/app/public/css/jstreetemplate.css
Normal file
@@ -0,0 +1,34 @@
|
||||
.jstree-anchor,
|
||||
.jstree-ocl {
|
||||
line-height: 20px !important;
|
||||
}
|
||||
|
||||
.jstree-anchor,
|
||||
.vakata-context {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.jstree-ocl {
|
||||
margin-top: -2px !important;
|
||||
}
|
||||
|
||||
.jstree-icon {
|
||||
line-height: 16px !important;
|
||||
transform: scale(1.4) !important;
|
||||
}
|
||||
|
||||
.jstree-node {
|
||||
min-height: 20px !important;
|
||||
line-height: 20px !important;
|
||||
}
|
||||
|
||||
.treedetail {
|
||||
border: 0.5px black solid;
|
||||
overflow: auto;
|
||||
box-shadow: 0 0 5px #ccc;
|
||||
}
|
||||
|
||||
.table td,
|
||||
.table th {
|
||||
vertical-align: inherit;
|
||||
}
|
||||
1
xxx/app/public/css/jstreetemplate.min.css
vendored
Normal file
1
xxx/app/public/css/jstreetemplate.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.jstree-anchor,.jstree-ocl{line-height:20px!important}.jstree-anchor,.vakata-context{font-size:16px}.jstree-ocl{margin-top:-2px!important}.jstree-icon{line-height:16px!important;transform:scale(1.4)!important}.jstree-node{min-height:20px!important;line-height:20px!important}.treedetail{border:.5px #000 solid;overflow:auto;box-shadow:0 0 5px #ccc}.table td,.table th{vertical-align:inherit}
|
||||
23
xxx/app/public/css/xxx.css
Normal file
23
xxx/app/public/css/xxx.css
Normal file
@@ -0,0 +1,23 @@
|
||||
body {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
min-height: 0px;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: fixed;
|
||||
bottom: 2px;
|
||||
right: 0px;
|
||||
}
|
||||
1
xxx/app/public/css/xxx.min.css
vendored
Normal file
1
xxx/app/public/css/xxx.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
body{width:100%;overflow:hidden;min-height:0;line-height:1.1}.navbar{padding-top:0;padding-bottom:0;height:50px}.navbar-brand{padding-top:0;padding-bottom:0}.footer{position:fixed;bottom:2px;right:0}
|
||||
BIN
xxx/app/public/images/powered.png
Normal file
BIN
xxx/app/public/images/powered.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
148
xxx/app/public/images/xxx.svg
Normal file
148
xxx/app/public/images/xxx.svg
Normal file
@@ -0,0 +1,148 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
sodipodi:docname="test.svg"
|
||||
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 84.957652 83.999998"
|
||||
height="84mm"
|
||||
width="84.957649mm"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs2">
|
||||
<linearGradient
|
||||
id="linearGradient2657"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#1d1c3a;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2655" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient2651"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2649" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="141.38559 : 23.558402 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="84.423113 : 12.065813 : 1"
|
||||
inkscape:persp3d-origin="42.478826 : 27.999999 : 1"
|
||||
id="perspective1152" />
|
||||
<rect
|
||||
id="rect1932"
|
||||
height="157.42708"
|
||||
width="145.8988"
|
||||
y="37.230656"
|
||||
x="21.922619" />
|
||||
<rect
|
||||
id="rect1925"
|
||||
height="154.78125"
|
||||
width="152.5134"
|
||||
y="30.994047"
|
||||
x="18.331844" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2657"
|
||||
id="linearGradient2653"
|
||||
x1="127.3954"
|
||||
y1="76.994209"
|
||||
x2="193.25467"
|
||||
y2="76.994209"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:window-y="1076"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-width="1920"
|
||||
showgrid="false"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:current-layer="text1919"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:cy="147.98735"
|
||||
inkscape:cx="168.44294"
|
||||
inkscape:zoom="1.979899"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
transform="translate(-32.673336,-72.980634)"
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Ebene 1">
|
||||
<g
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:50.8px;line-height:1.25;font-family:Gazzarelli;-inkscape-font-specification:Gazzarelli;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
id="text1919"
|
||||
aria-label="Ko Ma">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:44.3654px;line-height:1.65;font-family:'Gill Sans MT';-inkscape-font-specification:'Gill Sans MT';letter-spacing:0px;word-spacing:0px;stroke-width:0.0700042"
|
||||
x="36.218472"
|
||||
y="147.49475"
|
||||
id="text422"
|
||||
transform="scale(1.0102584,0.98984575)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan420"
|
||||
style="font-size:44.3654px;stroke-width:0.0700042"
|
||||
x="36.218472"
|
||||
y="147.49475">SVG</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:19.7556px;line-height:1.65;font-family:'Gill Sans MT';-inkscape-font-specification:'Gill Sans MT';letter-spacing:0px;word-spacing:0px;stroke-width:0.0700042"
|
||||
x="37.413837"
|
||||
y="98.903824"
|
||||
id="text426"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan424"
|
||||
style="font-size:19.7556px;stroke-width:0.0700042"
|
||||
x="37.413837"
|
||||
y="98.903824">xxx</tspan></text>
|
||||
<rect
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2653);stroke-width:1.229;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.2;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="rect1300"
|
||||
width="83.504608"
|
||||
height="82.438667"
|
||||
x="33.447392"
|
||||
y="73.72715"
|
||||
rx="7.6999998"
|
||||
ry="9.1999989" />
|
||||
</g>
|
||||
<g
|
||||
style="font-size:9.87778px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1925)"
|
||||
id="text1923" />
|
||||
<text
|
||||
style="font-size:9.87778px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1932)"
|
||||
id="text1930"
|
||||
xml:space="preserve" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.1 KiB |
174
xxx/app/public/js/jstreetemplate.js
Normal file
174
xxx/app/public/js/jstreetemplate.js
Normal file
@@ -0,0 +1,174 @@
|
||||
var tblmeta, nodeid, nodeselect, tree, table;
|
||||
var w = {
|
||||
autoclose: false,
|
||||
type: 'danger',
|
||||
top: false,
|
||||
rc0: {
|
||||
top: false,
|
||||
slide: true
|
||||
}
|
||||
};
|
||||
|
||||
var g = {
|
||||
autoclose: false,
|
||||
top: false,
|
||||
rc0: {
|
||||
top: false,
|
||||
slide: true
|
||||
}
|
||||
};
|
||||
|
||||
var option = '';
|
||||
|
||||
function init() {
|
||||
listtree();
|
||||
// JQuery Tooltips aktivieren
|
||||
$('[data-toggle="tooltip"]').tooltip({
|
||||
delay: {
|
||||
show: 1000,
|
||||
hide: 100
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function listtree() {
|
||||
$("#tree").jstree("destroy");
|
||||
|
||||
$.get($('#base_url').val() + '/api/jstreedata/', function (res) {
|
||||
//if ($.popyrc1(res, w)) return;
|
||||
$('#tree')
|
||||
.on('changed.jstree', function (e, data) {
|
||||
// klick auf einen Node und holen der Mitglieder
|
||||
if (data.node !== undefined) {
|
||||
nodeselect = data.node;
|
||||
treecklick(data);
|
||||
}
|
||||
})
|
||||
.jstree({
|
||||
'core': {
|
||||
"check_callback": function (operation, node, node_parent, node_position, more) {
|
||||
// unterbinden des droppen wenn man nicht owner ist und wenn externe sachen gedropt werden
|
||||
if (more && more.dnd && operation == 'move_node') {
|
||||
if (treelock || ogsidstochange[node_parent.id] == undefined) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
"keyboard": false,
|
||||
"cache": false,
|
||||
'data': res.data
|
||||
},
|
||||
"plugins": [
|
||||
"wholerow", "sort", "html_data"
|
||||
],
|
||||
}).on('ready.jstree', function (d) {
|
||||
$('.baum').show();
|
||||
});
|
||||
|
||||
$('.treedetail').css('height', 'calc(100vh - 130px)');
|
||||
});
|
||||
}
|
||||
|
||||
function treecklick(data) {
|
||||
$('.words').hide();
|
||||
if (data.node.parent != '#') {
|
||||
$('.words').show();
|
||||
gettabledata(data.node.id);
|
||||
}
|
||||
}
|
||||
|
||||
function gettabledata() {
|
||||
|
||||
table = $('#tbl-worlds').DataTable({
|
||||
ajax: {
|
||||
"type": "GET",
|
||||
"url": $('#base_url').val() + '/api/datatablesdata',
|
||||
dataSrc: function (json) {
|
||||
return json.data;
|
||||
}
|
||||
},
|
||||
// fixedHeader: {
|
||||
// header: true,
|
||||
// },
|
||||
// responsive: {
|
||||
// details: false
|
||||
// },
|
||||
// scrollCollapse: true,
|
||||
searching: true,
|
||||
destroy: true,
|
||||
deferRender: true,
|
||||
// createdRow: function (row, data, index) {
|
||||
// if (data.hidden == 1) {
|
||||
// $(row).css('opacity', 0.2)
|
||||
// }
|
||||
// },
|
||||
fixedColumns: {
|
||||
left: 1,
|
||||
right: 1
|
||||
},
|
||||
select: true,
|
||||
// "stateSave": true,
|
||||
// "stateLoadParams": function (settings, data) {
|
||||
// console.log(settings)
|
||||
// for (var i in data.columns) {
|
||||
// data.columns[i].regex = false;
|
||||
// data.columns[i].search = '';
|
||||
// }
|
||||
// },
|
||||
columns: [
|
||||
{
|
||||
data: 'col1',
|
||||
},
|
||||
{
|
||||
data: 'col2',
|
||||
},
|
||||
{
|
||||
data: 'col3',
|
||||
},
|
||||
{
|
||||
data: 'col4',
|
||||
},
|
||||
{
|
||||
data: 'col5',
|
||||
},
|
||||
{
|
||||
data: 'col6',
|
||||
},
|
||||
{
|
||||
data: 'col7',
|
||||
},
|
||||
{
|
||||
data: 'col8',
|
||||
},
|
||||
{
|
||||
data: 'col9',
|
||||
}
|
||||
],
|
||||
info: true,
|
||||
scrollX: true,
|
||||
// bLengthChange: false,
|
||||
scroller: true,
|
||||
scrollY: 'calc(100vh - 320px)', // Höhe der Tabelle
|
||||
"sDom": 'Bfrti',
|
||||
language: {
|
||||
sLoadingRecords: "Lade Wörter...",
|
||||
sInfo: '_START_ bis _END_ von _TOTAL_ Wörter',
|
||||
sInfoEmpty: '',
|
||||
infoFiltered: '(gefiltert von _MAX_ Wörter)',
|
||||
searchPlaceholder: 'Suche',
|
||||
sZeroRecords: 'Keine Wörter vorhanden.',
|
||||
sSearch: '',
|
||||
oPaginate: {
|
||||
sFirst: 'Erste',
|
||||
sPrevious: '<',
|
||||
sNext: '>',
|
||||
sLast: 'Letzte'
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
init();
|
||||
});
|
||||
1
xxx/app/public/js/jstreetemplate.min.js
vendored
Normal file
1
xxx/app/public/js/jstreetemplate.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
function init(){listtree(),$('[data-toggle="tooltip"]').tooltip({delay:{show:1e3,hide:100}})}function listtree(){$("#tree").jstree("destroy"),$.get($("#base_url").val()+"/api/jstreedata/",function(e){$("#tree").on("changed.jstree",function(e,t){void 0!==t.node&&(nodeselect=t.node,treecklick(t))}).jstree({core:{check_callback:function(e,t,a,o,r){if(r&&r.dnd&&"move_node"==e)return!treelock&&null!=ogsidstochange[a.id]},keyboard:!1,cache:!1,data:e.data},plugins:["wholerow","sort","html_data"]}).on("ready.jstree",function(e){$(".baum").show()}),$(".treedetail").css("height","calc(100vh - 130px)")})}function treecklick(e){$(".words").hide(),"#"!=e.node.parent&&($(".words").show(),gettabledata(e.node.id))}function gettabledata(){table=$("#tbl-worlds").DataTable({ajax:{type:"GET",url:$("#base_url").val()+"/api/datatablesdata",dataSrc:function(e){return e.data}},searching:!0,destroy:!0,deferRender:!0,fixedColumns:{left:1,right:1},select:!0,columns:[{data:"col1"},{data:"col2"},{data:"col3"},{data:"col4"},{data:"col5"},{data:"col6"},{data:"col7"},{data:"col8"},{data:"col9"}],info:!0,scrollX:!0,scroller:!0,scrollY:"calc(100vh - 320px)",sDom:"Bfrti",language:{sLoadingRecords:"Lade Wörter...",sInfo:"_START_ bis _END_ von _TOTAL_ Wörter",sInfoEmpty:"",infoFiltered:"(gefiltert von _MAX_ Wörter)",searchPlaceholder:"Suche",sZeroRecords:"Keine Wörter vorhanden.",sSearch:"",oPaginate:{sFirst:"Erste",sPrevious:"<",sNext:">",sLast:"Letzte"}}})}var tblmeta,nodeid,nodeselect,tree,table,w={autoclose:!1,type:"danger",top:!1,rc0:{top:!1,slide:!0}},g={autoclose:!1,top:!1,rc0:{top:!1,slide:!0}},option="";$(document).ready(function(){init()});
|
||||
7
xxx/app/public/js/xxx.js
Normal file
7
xxx/app/public/js/xxx.js
Normal file
@@ -0,0 +1,7 @@
|
||||
function xxx() {
|
||||
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
new xxx();
|
||||
});
|
||||
11
xxx/app/script/XxxApp
Normal file
11
xxx/app/script/XxxApp
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
BEGIN { unshift @INC, "$FindBin::Bin/../lib" }
|
||||
use Mojolicious::Commands;
|
||||
|
||||
# Start command line interface for application
|
||||
Mojolicious::Commands->start_app('XxxApp');
|
||||
108
xxx/app/t/01_routes.t
Normal file
108
xxx/app/t/01_routes.t
Normal file
@@ -0,0 +1,108 @@
|
||||
|
||||
print "Test: $0\n";
|
||||
|
||||
use Mojo::Base -strict;
|
||||
use Mojo::JSON qw(decode_json);
|
||||
use Modern::Perl;
|
||||
use Test::More;
|
||||
use Test::Mojo;
|
||||
use DBI;
|
||||
use Data::Printer;
|
||||
|
||||
#my $dbh = DBI->connect('DBI:mysql:prod:ares', '', '') or die ('Fehler beim Verbinden mit der Datenbank');
|
||||
my $t = Test::Mojo->new('XxxApp');
|
||||
|
||||
$t->app->log->level('info');
|
||||
$t->app->ua->max_redirects(1);
|
||||
|
||||
subtest 'prod konfig test' => sub {
|
||||
my $konf = do '../deb/prod/xxx_app.conf';
|
||||
|
||||
is exists $konf->{secret}, 1, 'secret = exists';
|
||||
is $konf->{htlib}, "/var/local/htlib", 'htlib = /var/local/htlib';
|
||||
|
||||
is $konf->{hypnotoad}->{pid_file}, "/run/xxx.pid", 'hypnotoad->pid_file = /run/xxx.pid';
|
||||
is $konf->{hypnotoad}->{workers}, 4, 'hypnotoad->workers = 4';
|
||||
is $konf->{hypnotoad}->{proxy}, 1, 'hypnotoad->proxy = 1';
|
||||
|
||||
is $konf->{logging}->{enable}, 1, 'logging->enable = 1';
|
||||
is $konf->{logging}->{facility}, 'local7', 'logging->facility = local7';
|
||||
is $konf->{logging}->{ident}, 'xxx', 'logging->ident = xxx';
|
||||
is $konf->{logging}->{level}, 'info', 'logging->level = info';
|
||||
is $konf->{logging}->{only_syslog}, 1, 'logging->only_syslog = 1';
|
||||
};
|
||||
|
||||
subtest 'Routes', sub {
|
||||
note '/';
|
||||
$t->get_ok('/')
|
||||
->status_is(200)
|
||||
->content_like(qr'<img class="mypic" src="\/images\/xxx.svg">', 'SVG is availble')
|
||||
->header_isnt('Server' => 'Mojolicious');
|
||||
|
||||
note '/login';
|
||||
$t->get_ok('/login')
|
||||
->status_is(200)
|
||||
->content_like(qr'placeholder="Anmeldename"', 'Anmeldename is availble')
|
||||
->content_like(qr'placeholder="Passwort"', 'Passwort is availble');
|
||||
|
||||
note '/api/jstreedata no permission';
|
||||
$t->get_ok('/api/jstreedata')
|
||||
->status_is(401);
|
||||
|
||||
note '/api/datatablesdata no permission';
|
||||
$t->get_ok('/api/datatablesdata')
|
||||
->status_is(401);
|
||||
|
||||
# on this point we have a session
|
||||
note 'with Login no AD';
|
||||
$t->post_ok(
|
||||
'/login' => form => { username => 'developer', password => 'wbdfgmnjke834dshf89w7rsdfsdjf' }
|
||||
);
|
||||
$t->status_is(302);
|
||||
|
||||
note '/api/jstreedata';
|
||||
$t->get_ok('/api/jstreedata')
|
||||
->status_is(200)
|
||||
->json_is( '/msg' => 'OK', 'msg: OK' )
|
||||
->json_is( '/rc' => 0, 'rc: 0' );
|
||||
my $res = $t->tx->res->json;
|
||||
is ref $res->{data}, 'ARRAY', 'data is ARRAY reference';
|
||||
is exists $res->{data}[0]->{id}, 1, 'data has id';
|
||||
is exists $res->{data}[0]->{parent}, 1, 'data has firstname';
|
||||
is exists $res->{data}[0]->{text}, 1, 'data has name';
|
||||
|
||||
note '/api/datatablesdata';
|
||||
$t->get_ok('/api/datatablesdata')
|
||||
->status_is(200)
|
||||
->json_is( '/msg' => 'OK', 'msg: OK' )
|
||||
->json_is( '/rc' => 0, 'rc: 0' );
|
||||
$res = $t->tx->res->json;
|
||||
is ref $res->{data}, 'ARRAY', 'data is ARRAY reference';
|
||||
is exists $res->{data}[0]->{col1}, 1, 'data has col1';
|
||||
is exists $res->{data}[0]->{col2}, 1, 'data has col2';
|
||||
is exists $res->{data}[0]->{col3}, 1, 'data has col3';
|
||||
is exists $res->{data}[0]->{col4}, 1, 'data has col4';
|
||||
is exists $res->{data}[0]->{col5}, 1, 'data has col5';
|
||||
is exists $res->{data}[0]->{col6}, 1, 'data has col6';
|
||||
is exists $res->{data}[0]->{col7}, 1, 'data has col7';
|
||||
is exists $res->{data}[0]->{col8}, 1, 'data has col8';
|
||||
is exists $res->{data}[0]->{col9}, 1, 'data has col9';
|
||||
is exists $res->{data}[0]->{col10}, '', 'data has no col10';
|
||||
};
|
||||
|
||||
subtest 'POST requestBody required must True', sub {
|
||||
$t->get_ok('/api');
|
||||
$t->status_is(200);
|
||||
|
||||
my $res = $t->tx->res->json;
|
||||
|
||||
for my $path ( keys %{$res->{paths}} ) {
|
||||
my $pa = $res->{paths}->{$path};
|
||||
if ( $pa->{post}->{requestBody} ) {
|
||||
is $pa->{post}->{requestBody}->{required}, 1, $path;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
done_testing();
|
||||
119
xxx/app/templates/layouts/index.html.ep
Normal file
119
xxx/app/templates/layouts/index.html.ep
Normal file
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title><%= $title %></title>
|
||||
|
||||
%= stylesheet '/htlib/bootstrap/5.3.3/css/bootstrap.min.css'
|
||||
%= stylesheet '/htlib/fontawesome/6.4.0/css/all.min.css'
|
||||
%= stylesheet '/htlib/jquery-datatables/2.1.8/css/dataTables.bootstrap4.min.css'
|
||||
%= stylesheet '/htlib/jquery-datatables/extensions/Buttons/3.1.2/css/buttons.dataTables.min.css'
|
||||
%= stylesheet '/htlib/jquery-datatables/extensions/Scroller/2.4.3/css/scroller.bootstrap4.min.css'
|
||||
%= stylesheet '/htlib/jquery-datatables/extensions/FixedColumns/5.0.3/css/fixedColumns.dataTables.min.css'
|
||||
%= stylesheet '/htlib/jquery-ui/1.13.2/jquery-ui.min.css'
|
||||
%= stylesheet '/css/xxx.min.css'
|
||||
|
||||
<style>
|
||||
% if ( $self->config->{test} ) { # einfärben der Kopfzeile wenn Programm im Developermodus läuft
|
||||
.navbar {
|
||||
background-color: rgb(255, 215, 215) !important;
|
||||
}
|
||||
% }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Standard-Navbar -->
|
||||
|
||||
<nav class="navbar navbar-expand-sm navbar-light bg-light">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="<%= $self->config->{mlandshome} %>">
|
||||
<img src="<%= url_for('/htlib/mlands/img/mlands.svg') %>">
|
||||
</a>
|
||||
<a class="navbar-brand ukraine" href="/" style="margin-right: 0.5rem;">
|
||||
<img src="<%= url_for('/images/xxx.svg') %>" width="40px">
|
||||
</a>
|
||||
<a class="navbar-brand" style="font-size: 1.4rem;" href="<%= url_for('/') %>">Xxx</a>
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<%== nav($self->config->{navigation}->{menu}) %>
|
||||
</ul>
|
||||
</ul>
|
||||
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
|
||||
<ul class="navbar-nav nav">
|
||||
% if ( $self->session->{auth_data}) {
|
||||
% my $username = $self->session->{auth_data} =~ s/@[^@]*$//r;
|
||||
<li class="nav-item dropdown">
|
||||
<a aria-expanded="false" aria-haspopup="true" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" id="navbarDropdown" role="button">
|
||||
%== $username
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu dropdown-menu-lg-right">
|
||||
%# Benutzerinformatioen
|
||||
<li><a href="<%= url_for('/userinfo') %>" class="dropdown-item">
|
||||
<span class="fas fa-user-circle" style="color:#777;"></span>
|
||||
Info
|
||||
</a></li>
|
||||
<li class="dropdown-divider"></li>
|
||||
%# Abmelden
|
||||
<li><a class="dropdown-item"href="<%= url_for('/getoff') %>">
|
||||
<span class="fas fa-cloud-moon" style="color:#777;"></span>
|
||||
Abmelden
|
||||
</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
% } else {
|
||||
<li class="nav-item">
|
||||
<a href="<%= url_for('/login') %>" class="nav-link">
|
||||
Anmelden
|
||||
<span class="fas fa-lock" style="color:#777;"></span>
|
||||
</a>
|
||||
</li>
|
||||
% }
|
||||
<li>
|
||||
<a href="<%= url_for('/about') %>" class="nav-link">
|
||||
über
|
||||
<span class="fas fa-info-sign" style="color:#777;"></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- externe Bibliotheken -->
|
||||
%= javascript '/htlib/jquery/3.7.1/jquery.min.js'
|
||||
%= javascript '/htlib/jquery-ui/1.13.2/jquery-ui.min.js'
|
||||
%= javascript '/htlib/bootstrap/5.3.3/js/bootstrap.bundle.min.js'
|
||||
%= javascript '/htlib/jquery-datatables/2.1.8/js/dataTables.min.js'
|
||||
%= javascript '/htlib/jquery-datatables/2.1.8/js/dataTables.bootstrap4.min.js'
|
||||
%= javascript '/htlib/jquery-datatables/extensions/Select/2.1.0/js/dataTables.select.min.js'
|
||||
%= javascript '/htlib/jquery-datatables/extensions/Select/2.1.0/js/select.bootstrap4.min.js'
|
||||
%= javascript '/htlib/jquery-datatables/extensions/Buttons/3.1.2/js/dataTables.buttons.min.js'
|
||||
%= javascript '/htlib/jquery-datatables/extensions/Buttons/3.1.2/js/buttons.colVis.min.js'
|
||||
%= javascript '/htlib/jquery-datatables/extensions/JSZip/3.10.1/jszip.min.js'
|
||||
%= javascript '/htlib/jquery-datatables/extensions/pdfmake/0.2.7/pdfmake.min.js'
|
||||
%= javascript '/htlib/jquery-datatables/extensions/pdfmake/0.2.7/vfs_fonts.js'
|
||||
%= javascript '/htlib/jquery-datatables/extensions/Buttons/3.1.2/js/buttons.html5.min.js'
|
||||
%= javascript "/htlib/jquery-datatables/extensions/FixedColumns/5.0.3/js/dataTables.fixedColumns.min.js"
|
||||
%= javascript '/htlib/jquery-datatables/extensions/Scroller/2.4.3/js/dataTables.scroller.min.js'
|
||||
%= javascript '/htlib/jquery-datatables/extensions/Scroller/2.4.3/js/scroller.bootstrap4.min.js'
|
||||
%= javascript '/htlib/jquery-datatables/date-de/date-de.min.js'
|
||||
|
||||
%= javascript "/htlib/mlands/js/popy.min.js"
|
||||
|
||||
<%= content %>
|
||||
|
||||
<input type="hidden" id="base_url" value="<%= $self->config->{prefix} %>">
|
||||
<input type="hidden" id="koma-urlbase" value="<%= $self->config->{base}->{koma}->{url} %>">
|
||||
<!-- FOOTER -->
|
||||
<footer class="footer">
|
||||
% use POSIX qw(strftime);
|
||||
% my $year = strftime('%Y', localtime);
|
||||
<div class="container-fluid text-muted text-right">
|
||||
<small>Xxx v<%= $self->config->{version} %> • © 2003-<%= $year %> ml&s Gmbh & Co. KG</small>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
16
xxx/app/templates/main/about.html.ep
Normal file
16
xxx/app/templates/main/about.html.ep
Normal file
@@ -0,0 +1,16 @@
|
||||
% layout 'index';
|
||||
|
||||
<div class="container pt-3">
|
||||
<div class="jumbotron">
|
||||
<p>Entwickler: <br></p>
|
||||
<h4><p></p>
|
||||
<p>Version <%= $self->config->{version} %><p>
|
||||
<p>powered by</p>
|
||||
<img src="<%= url_for('/images/powered.png') %>"><br>
|
||||
<p><a href="https://mojolicious.org/" target="_blank">Mojolicious</a> <%== 'V'.$Mojolicious::VERSION .', <a href="https://perl.org/" target="_blank">Perl</a> '.ucfirst $^V .', ' %><span id="version"></span></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$('#version').html('<a href="https://jquery.com/" target="_blank">jQuery</a> V' + $().jquery + ', <a href="https://datatables.net/" target="_blank">Datatables</a> V' + $.fn.dataTable.version + ', <a href="https://getbootstrap.com/docs/3.3/" target="_blank">Bootstrap</a> V' + bootstrap.Tooltip.VERSION );
|
||||
</script>
|
||||
35
xxx/app/templates/main/loginform.html.ep
Normal file
35
xxx/app/templates/main/loginform.html.ep
Normal file
@@ -0,0 +1,35 @@
|
||||
% layout 'index';
|
||||
|
||||
<title>Xxx: Login</title>
|
||||
|
||||
<div class="container">
|
||||
%= form_for '/login' => {format => 'txt'} => (method => 'POST', class => 'form-horizontal', id => 'form_login') => begin
|
||||
|
||||
<fieldset>
|
||||
<div class="row" style="margin-top:25vh;">
|
||||
<div class="col-4" style="margin:0 auto 0 auto;float:none;">
|
||||
% if ( defined $self->session->{msg} ) {
|
||||
<h4>
|
||||
% if ( $self->session->{msg} =~ /Fehler|Sorry/ ) {
|
||||
<span class="text-danger">
|
||||
% } else {
|
||||
<span class="text-info">
|
||||
% }
|
||||
<%= $self->session->{msg} %>
|
||||
</span>
|
||||
</h4>
|
||||
% }
|
||||
<div class="input-group">
|
||||
<div class="input-group-text"><i class="fas fa-user"></i></div>
|
||||
<input autocomplete="off" autofocus="" class="form-control" id="id_username" name="username" placeholder="Anmeldename" required="" type="text">
|
||||
</div>
|
||||
<div class="input-group pt-3">
|
||||
<div class="input-group-text"><i class="fas fa-lock"></i></div>
|
||||
<input class="form-control" id="id_password" name="password" placeholder="Passwort" required="" type="password" value="">
|
||||
</div>
|
||||
<div class="pt-3"><input class="btn btn-lg btn-primary btn-block" type="submit" value="Anmelden"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
% end
|
||||
|
||||
</div>
|
||||
16
xxx/app/templates/main/main.html.ep
Normal file
16
xxx/app/templates/main/main.html.ep
Normal file
@@ -0,0 +1,16 @@
|
||||
% layout 'index';
|
||||
<style>
|
||||
.mypic {
|
||||
height: calc(100vh - 180px);
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<div class="card m-2">
|
||||
<div class="row p-3">
|
||||
<div>Willkommen bei</div>
|
||||
</div>
|
||||
<div class="text-center pb-3">
|
||||
<img class="mypic" src="/images/xxx.svg">
|
||||
</div>
|
||||
</div>
|
||||
23
xxx/app/templates/main/userinfo.html.ep
Normal file
23
xxx/app/templates/main/userinfo.html.ep
Normal file
@@ -0,0 +1,23 @@
|
||||
% layout 'index';
|
||||
|
||||
<title>*Temp*::Userinfo</title>
|
||||
|
||||
<div class="jumbotron" style="margin-top:5vh;">
|
||||
|
||||
% if ( defined $msg ) {
|
||||
<h2>
|
||||
% if ( $msg =~ /Fehler|Sorry/ ) {
|
||||
<span class="text-danger">
|
||||
% } else {
|
||||
<span class="text-info">
|
||||
% }
|
||||
<%= $msg %></span></h2>
|
||||
% }
|
||||
|
||||
% if ( defined $sess->{privs} ) {
|
||||
% foreach my $s ( @{$sess->{privs} } ) {
|
||||
<p> Gruppe: <%= $s %></p>
|
||||
% }
|
||||
% }
|
||||
|
||||
</div>
|
||||
43
xxx/app/templates/menu/jstreetemplate.html.ep
Normal file
43
xxx/app/templates/menu/jstreetemplate.html.ep
Normal file
@@ -0,0 +1,43 @@
|
||||
% layout 'index';
|
||||
|
||||
%= stylesheet '/htlib/jquery-jstree/3.3.17/themes/default/style.min.css'
|
||||
%= stylesheet '/css/jstreetemplate.min.css'
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row p-2">
|
||||
<div class="col-3">
|
||||
<label class="col-form-label text-right">Daten:</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row pr-3 baum" style="display: none">
|
||||
<div class="col-3">
|
||||
<div class="treedetail" id="tree"></div>
|
||||
</div>
|
||||
<div class="col-9 treedetail">
|
||||
<div class="words" style="display: none">
|
||||
<div class="row p-3">
|
||||
<label class="col-form-label pb-0">Wörter</label>
|
||||
</div>
|
||||
<table class="table table-bordered table-sm" width="100%" id="tbl-worlds">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">Spalte1</th>
|
||||
<th class="text-center">Spalte 2</th>
|
||||
<th class="text-center">Spalte 3</th>
|
||||
<th class="text-center">Spalte 4</th>
|
||||
<th class="text-center">Spalte 5</th>
|
||||
<th class="text-center">Spalte 6</th>
|
||||
<th class="text-center">Spalte 7</th>
|
||||
<th class="text-center">Spalte 8</th>
|
||||
<th class="text-center">Spalte 9</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
%= javascript '/htlib/jquery-jstree/3.3.17/jstree.min.js'
|
||||
%= javascript "/js/jstreetemplate.min.js?v=". $self->config->{version}
|
||||
13
xxx/app/test.sh
Normal file
13
xxx/app/test.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
#export PERL5LIB=`pwd`
|
||||
|
||||
if [[ $1 == "all" ]]; then
|
||||
prove -l t/*.t
|
||||
else
|
||||
if [[ -f t/$1.t ]]; then
|
||||
prove -l -v t/$1.t
|
||||
else
|
||||
prove -l -v t/*.t
|
||||
fi
|
||||
fi
|
||||
35
xxx/app/xxx_app.conf
Normal file
35
xxx/app/xxx_app.conf
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
# zus_config => '/etc/mlands/configs/xxx.conf', # um externe konfigs mit Passwörtern zu laden
|
||||
|
||||
htlib => '/var/local/htlib',
|
||||
mlandshome => 'http://intranet.mlands.com:9673/Z/',
|
||||
komaurl => 'http://intra/koma',
|
||||
smtpserver => 'mail.mlands.com',
|
||||
mail => 'Xxx@mlands.com',
|
||||
|
||||
secret => 'mojoappsecret',
|
||||
|
||||
# DB Pools
|
||||
# db => {
|
||||
# xxx => {
|
||||
# dsn => 'DBI:mysql:test:localhost',
|
||||
# username => '',
|
||||
# password => '',
|
||||
# verbose => 0,
|
||||
# },
|
||||
# },
|
||||
|
||||
privileges => {
|
||||
# user => wird bei erfolgreicher Anmeldung den Privs hinzugefügt
|
||||
},
|
||||
|
||||
logging => {
|
||||
level => 'debug',
|
||||
facility => 'local7',
|
||||
enable => 1,
|
||||
only_syslog => 0,
|
||||
#access_log => 'v1', #bisher nicht änderbar
|
||||
ident => 'xxx',
|
||||
#color => 1, #erst ab Mojolicious 9.01
|
||||
}
|
||||
}
|
||||
1
xxx/deb/DEBIAN/conffiles
Normal file
1
xxx/deb/DEBIAN/conffiles
Normal file
@@ -0,0 +1 @@
|
||||
/opt/xxx/app/xxx_app.conf
|
||||
10
xxx/deb/DEBIAN/control
Normal file
10
xxx/deb/DEBIAN/control
Normal file
@@ -0,0 +1,10 @@
|
||||
Package: steffen-xxx
|
||||
Version: __VERSION__
|
||||
Section: unknown
|
||||
Priority: optional
|
||||
Architecture: all
|
||||
Depends: libmojolicious-perl >= (9.39), libev-perl, libsteffen-mojoplug-authorization-perl, libsteffen-mojoplug-navhelper-perl, libsteffen-mojoplug-syslog-perl, libmojolicious-plugin-openapi-perl, libsteffen-mojoplug-swaggerui-perl
|
||||
Installed-Size: __VERSION__
|
||||
Maintainer: Steffen Junge <steffen.junge@gmx.de>
|
||||
Description: wofuer
|
||||
A HTTP Daemon for the steffen xxx Webservice.
|
||||
7
xxx/deb/DEBIAN/postinst
Normal file
7
xxx/deb/DEBIAN/postinst
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Startskript aktivieren
|
||||
systemctl daemon-reload
|
||||
/bin/systemd-sysusers
|
||||
/bin/systemd-tmpfiles --create
|
||||
systemctl enable --now steffen-xxx.service
|
||||
6
xxx/deb/DEBIAN/prerm
Normal file
6
xxx/deb/DEBIAN/prerm
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
# $Id$
|
||||
|
||||
# Daemon stoppen und deaktivieren
|
||||
systemctl stop steffen-xxx.service || true
|
||||
systemctl disable steffen-xxx.service || true
|
||||
52
xxx/deb/pbuild.sh
Normal file
52
xxx/deb/pbuild.sh
Normal file
@@ -0,0 +1,52 @@
|
||||
#! /bin/sh
|
||||
cd "${0%/*}" || exit
|
||||
SCRIPTPATH=$(pwd)
|
||||
cd ../app || exit
|
||||
rc=0
|
||||
prove -l -v t/*.t
|
||||
rc=$?
|
||||
cd "$SCRIPTPATH" || exit
|
||||
|
||||
if [ $rc -eq 0 ] ; then
|
||||
# Jahr in dem das Programm begonnen wurde
|
||||
createyear=mojocreateyear
|
||||
currentyear=$(date +'%Y')
|
||||
major=$((currentyear-createyear))
|
||||
minor=$(date +'%m')
|
||||
|
||||
progpfad="opt/xxx/"
|
||||
apppfad="app/lib/XxxApp.pm"
|
||||
workdir=/tmp/$USER_$(pwd | sed 's/^.*\///')
|
||||
rm -Rf "${workdir:?}/*"
|
||||
mkdir -p "$workdir"
|
||||
# Daten in workdir sysnchronisieren
|
||||
rsync -Ca ./DEBIAN "$workdir/"
|
||||
rsync -Ca ./usr "$workdir/"
|
||||
mkdir -p "$workdir/opt"
|
||||
rsync -Ca ../app "$workdir/$progpfad"
|
||||
|
||||
# Test entfernen
|
||||
rm -r "$workdir/$progpfad/app/t"
|
||||
rm "$workdir/$progpfad/app/test.sh"
|
||||
|
||||
# config aus prod ordner kopieren
|
||||
cp -ar ./prod/* "$workdir/$progpfad/app"
|
||||
|
||||
# Revision holen
|
||||
REV=$(git rev-list --count --all)
|
||||
VER="$major.$minor.$REV"
|
||||
|
||||
# Version in die startup app.pm und control eintragen
|
||||
sed -i "s@__VERSION__@$VER@g" "$workdir/DEBIAN/control"
|
||||
sed -i "s@__VERSION__@$VER@g" "$workdir/$progpfad/$apppfad"
|
||||
|
||||
SIZE=$(du -h -k --max-depth=0 "$workdir" | cut -d '/' -f1)
|
||||
sed -i "s@__SIZE__@$SIZE@g" "$workdir/DEBIAN/control"
|
||||
echo "Version: $VER, Size: $SIZE"
|
||||
|
||||
chmod -R g-s "$workdir"
|
||||
# paket erstellen
|
||||
fakeroot dpkg-deb -b "$workdir" ./
|
||||
else
|
||||
echo "TESTs failed no package created"
|
||||
fi
|
||||
40
xxx/deb/prod/xxx_app.conf
Normal file
40
xxx/deb/prod/xxx_app.conf
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
# zus_config => '/etc/mlands/configs/xxx.conf', # um externe konfigs mit Passwörtern zu laden
|
||||
|
||||
htlib => '/var/local/htlib',
|
||||
|
||||
secret => 'mojoappsecret',
|
||||
|
||||
# dieser Teil wandert in die Datei unter zus_config
|
||||
# DB Pools
|
||||
# db => {
|
||||
# xxx => {
|
||||
# dsn => 'DBI:mysql:test:ares',
|
||||
# username => '',
|
||||
# password => '',
|
||||
# verbose => 0,
|
||||
# },
|
||||
# },
|
||||
|
||||
hypnotoad => {
|
||||
listen => ['http://*:hypnotoadport'],
|
||||
workers => 4,
|
||||
pid_file => '/run/xxx.pid',
|
||||
proxy => 1
|
||||
},
|
||||
|
||||
privileges => {
|
||||
# user => wird bei erfolgreicher Anmeldung den Privs hinzugefügt
|
||||
# admin => 'xxx_admin::xgroups',
|
||||
},
|
||||
|
||||
logging => {
|
||||
level => 'info',
|
||||
facility => 'local7',
|
||||
enable => 1,
|
||||
only_syslog => 1,
|
||||
#access_log => 'v1', #bisher nicht änderbar
|
||||
ident => 'xxx',
|
||||
#color => 1, #erst ab Mojolicious 9.01
|
||||
}
|
||||
}
|
||||
41
xxx/deb/usr/lib/systemd/system/steffen-xxx.service
Normal file
41
xxx/deb/usr/lib/systemd/system/steffen-xxx.service
Normal file
@@ -0,0 +1,41 @@
|
||||
[Unit]
|
||||
Description=steffen Xxx/Rfs Webservice
|
||||
After=network.target syslog.socket
|
||||
StartLimitBurst=5
|
||||
StartLimitIntervalSec=10
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
User=steffen-xxx
|
||||
Group=webapps
|
||||
WorkingDirectory=/opt/xxx/app
|
||||
ExecStart=/usr/bin/hypnotoad ./script/XxxApp
|
||||
ExecReload=/usr/bin/hypnotoad ./script/XxxApp
|
||||
Restart=on-failure
|
||||
PIDFile=/run/xxx.pid
|
||||
KillMode=process
|
||||
|
||||
# Optional hardening to improve security
|
||||
ReadWritePaths=/opt/xxx
|
||||
NoNewPrivileges=yes
|
||||
MemoryDenyWriteExecute=true
|
||||
PrivateDevices=yes
|
||||
PrivateTmp=yes
|
||||
ProtectHome=yes
|
||||
#ProtectSystem=strict
|
||||
ProtectControlGroups=true
|
||||
#RestrictSUIDSGID=true
|
||||
RestrictRealtime=true
|
||||
LockPersonality=true
|
||||
#ProtectKernelLogs=true
|
||||
ProtectKernelTunables=true
|
||||
#ProtectHostname=true
|
||||
ProtectKernelModules=true
|
||||
PrivateUsers=true
|
||||
#ProtectClock=true
|
||||
SystemCallArchitectures=native
|
||||
SystemCallErrorNumber=EPERM
|
||||
SystemCallFilter=@system-service
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
5
xxx/deb/usr/lib/sysusers.d/steffen-xxx.conf
Normal file
5
xxx/deb/usr/lib/sysusers.d/steffen-xxx.conf
Normal file
@@ -0,0 +1,5 @@
|
||||
# see https://www.freedesktop.org/software/systemd/man/latest/sysusers.d.html
|
||||
# Type Name ID GECOS Home Shell
|
||||
g webapps - -
|
||||
u steffen-xxx - "steffen Xxx" /opt/xxx -
|
||||
m steffen-xxx webapps
|
||||
3
xxx/deb/usr/lib/tmpfiles.d/steffen-xxx.conf
Normal file
3
xxx/deb/usr/lib/tmpfiles.d/steffen-xxx.conf
Normal file
@@ -0,0 +1,3 @@
|
||||
# see https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html
|
||||
# Type Path Mode User Group Age Argument
|
||||
Z /opt/xxx - steffen-xxx steffen-xxx
|
||||
Reference in New Issue
Block a user