From fde661bcc2faa20f26101e7b2f34b0735e5118d2 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Tue, 7 Aug 2007 15:56:20 +0000 Subject: [PATCH] Initialer CheckIn git-svn-id: http://svn.brehm-online.com/svn/cookbook/trunk@3 191103c4-1d37-0410-b3e5-d8c2315c0aac --- Changes | 4 + Makefile.PL | 16 + README | 1 + cookbook.yml | 2 + lib/CookBook.pm | 70 +++ lib/CookBook/Common.pm | 430 ++++++++++++++++++ lib/CookBook/Common.pm.bak | 429 +++++++++++++++++ lib/CookBook/Controller/Root.pm | 55 +++ root/favicon.ico | Bin 0 -> 2551 bytes root/static/images/btn_120x50_built.png | Bin 0 -> 3826 bytes .../static/images/btn_120x50_built_shadow.png | Bin 0 -> 3681 bytes root/static/images/btn_120x50_powered.png | Bin 0 -> 3862 bytes .../images/btn_120x50_powered_shadow.png | Bin 0 -> 3673 bytes root/static/images/btn_88x31_built.png | Bin 0 -> 2517 bytes root/static/images/btn_88x31_built_shadow.png | Bin 0 -> 2274 bytes root/static/images/btn_88x31_powered.png | Bin 0 -> 2542 bytes .../images/btn_88x31_powered_shadow.png | Bin 0 -> 2304 bytes root/static/images/catalyst_logo.png | Bin 0 -> 13710 bytes script/cookbook_cgi.pl | 37 ++ script/cookbook_create.pl | 74 +++ script/cookbook_fastcgi.pl | 80 ++++ script/cookbook_server.pl | 111 +++++ script/cookbook_test.pl | 54 +++ t/01app.t | 7 + t/02pod.t | 9 + t/03podcoverage.t | 9 + 26 files changed, 1388 insertions(+) create mode 100644 Changes create mode 100644 Makefile.PL create mode 100644 README create mode 100644 cookbook.yml create mode 100644 lib/CookBook.pm create mode 100644 lib/CookBook/Common.pm create mode 100644 lib/CookBook/Common.pm.bak create mode 100644 lib/CookBook/Controller/Root.pm create mode 100644 root/favicon.ico create mode 100644 root/static/images/btn_120x50_built.png create mode 100644 root/static/images/btn_120x50_built_shadow.png create mode 100644 root/static/images/btn_120x50_powered.png create mode 100644 root/static/images/btn_120x50_powered_shadow.png create mode 100644 root/static/images/btn_88x31_built.png create mode 100644 root/static/images/btn_88x31_built_shadow.png create mode 100644 root/static/images/btn_88x31_powered.png create mode 100644 root/static/images/btn_88x31_powered_shadow.png create mode 100644 root/static/images/catalyst_logo.png create mode 100755 script/cookbook_cgi.pl create mode 100755 script/cookbook_create.pl create mode 100755 script/cookbook_fastcgi.pl create mode 100755 script/cookbook_server.pl create mode 100755 script/cookbook_test.pl create mode 100644 t/01app.t create mode 100644 t/02pod.t create mode 100644 t/03podcoverage.t diff --git a/Changes b/Changes new file mode 100644 index 0000000..5d532d6 --- /dev/null +++ b/Changes @@ -0,0 +1,4 @@ +This file documents the revision history for Perl extension CookBook. + +0.01 2007-08-07 15:57:22 + - initial revision, generated by Catalyst diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..400eb0f --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,16 @@ +use inc::Module::Install; + +name 'CookBook'; +all_from 'lib/CookBook.pm'; + +requires 'Catalyst' => '5.7007'; +requires 'Catalyst::Plugin::ConfigLoader'; +requires 'Catalyst::Plugin::Static::Simple'; +requires 'Catalyst::Action::RenderView'; +requires 'YAML'; # This should reflect the config file format you've chosen + # See Catalyst::Plugin::ConfigLoader for supported formats +catalyst; + +install_script glob('script/*.pl'); +auto_install; +WriteAll; diff --git a/README b/README new file mode 100644 index 0000000..a59fec5 --- /dev/null +++ b/README @@ -0,0 +1 @@ +Run script/cookbook_server.pl to test the application. diff --git a/cookbook.yml b/cookbook.yml new file mode 100644 index 0000000..c2f5dab --- /dev/null +++ b/cookbook.yml @@ -0,0 +1,2 @@ +--- +name: CookBook diff --git a/lib/CookBook.pm b/lib/CookBook.pm new file mode 100644 index 0000000..51f92dc --- /dev/null +++ b/lib/CookBook.pm @@ -0,0 +1,70 @@ +package CookBook; + +# $Id: CIT.pm 69 2007-06-27 12:55:47Z fbrehm $ +# $URL: http://maria.technik.berlin.strato.de:8080/svn-cit/trunk/CIT/lib/CIT.pm $ + +use strict; +use warnings; + +use Catalyst::Runtime '5.70'; + +# Set flags and add plugins for the application +# +# ConfigLoader: will load the configuration from a YAML file in the +# application's home directory +# Static::Simple: will serve static files from the application's root +# directory + +use Catalyst qw/ + + ConfigLoader + + Static::Simple + +/; + +our $VERSION = '0.01'; + +# Configure the application. +# +# Note that settings in CookBook.yml (or other external +# configuration file that you set up manually) take precedence +# over this when using ConfigLoader. Thus configuration +# details given here can function as a default configuration, +# with a external configuration file acting as an override for +# local deployment. + +__PACKAGE__->config( name => 'CookBook' ); + +# Start the application +__PACKAGE__->setup; + + +=head1 NAME + +CookBook - Catalyst based application + +=head1 SYNOPSIS + + script/cookbook_server.pl + +=head1 DESCRIPTION + +[enter your description here] + +=head1 SEE ALSO + +L, L + +=head1 AUTHOR + +Frank Brehm + +=head1 LICENSE + +This library is free software, you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +1; diff --git a/lib/CookBook/Common.pm b/lib/CookBook/Common.pm new file mode 100644 index 0000000..7643f99 --- /dev/null +++ b/lib/CookBook/Common.pm @@ -0,0 +1,430 @@ +package CookBook::Common; + +# $Id: Common.pm 69 2007-06-27 12:55:47Z fbrehm $ +# $URL: http://maria.technik.berlin.strato.de:8080/svn-cit/trunk/CIT/lib/CIT/Common.pm $ + +=head1 NAME + +CookBook::Common + +=head1 DESCRIPTION + +Modul fuer allgemeine Aufgaben, zum Beispiel Verbose-Level usw. + +Dieses Modul sollte von allen Scripten und Modulen verwendet werden. + +=cut + +#--------------------------------------------------------------------------- + +use strict; +use warnings; +use Exporter; +use Data::Dumper; +use Cwd; +use File::Spec; + +use Carp qw(:DEFAULT cluck); + +our @ISA = qw(Exporter); +our @EXPORT = qw( + &verbose + &canon_filename + &common_debug + &common_error + &common_notice + &get_output_string + &escape_html + &home_dir + &to_bool + &to_float + &to_int +); + +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; + +our $COOKBOOK_VERSION = "1.1"; +our $AUTHOR = 'Frank Brehm '; + +our $env_home_name = 'COOKBOOK_HOME'; + +my $Revis = <<'ENDE'; + $Revision: 69 $ +ENDE +$Revis =~ s/^.*:\s*(\S+)\s*\$.*/$1/s; +our $VERSION = $COOKBOOK_VERSION . "." . $Revis; + +my $verbose = 0; +my $mark = 'CookBook'; + +#------------------------------------------------------------------------------------------ + +=head1 Funktionen + +Alle hier definierten Funktionen werden exportiert. + +#------------------------------------------------------------------------------------------ + +=head2 verbose( $new_verbose_level ) + +Setzt bzw. gibt den Verbose-Level des aktuellen Scripts zurueck. + +Typische Werte: + +=over 4 + +=item I<0>: + +Keinerlei Ausgaben. + +=item I<1>: + +Ausgabe der wichtigsten Aktionen des aktuellen Scripts (sollte eigentlich Standard sein). + +. +. +. + +=item I<6>: + +Ausfuehrlichstes Geplapper bis zum Gehtnichtmehr. + +=back + +=cut + +sub verbose { + + my $new_verbose_level = shift; + + if ( defined $new_verbose_level and $new_verbose_level =~ /^\d+$/ ) { + $verbose = $new_verbose_level; + } + + return $verbose; + +} ## end sub verbose + +##------------------------------------------------------------------------------------------ + +=head2 mark( [$new_mark] ) + +Gibt den aktuellen Log-Marker zurueck bzw. setzt einen neuen, wenn er übergeben wurde. + +=cut + +sub mark { + + my $new_mark = shift; + + if ( $new_mark and $new_mark !~ /^\s*$/ ) { + $new_mark =~ s/^\s+//; + $new_mark =~ s/\s+$//s; + $mark = $new_mark; + } + + return $mark; + +} ## end sub mark + +#------------------------------------------------------------------------------------------ + +=head2 home_dir() + +Gibt den Namen des Verzeichnisses der Software-Installation zurueck, +die aus der Umgebungsvariablen C entnommen wird. + +Wenn die Umgebungsvariable nicht gesetzt ist bzw. auf ein nicht vorhandenes Verzeichnis +zeigt, wird undef zurueckgegeben. + +=cut + +sub home_dir { + + my $K = __PACKAGE__ . "::home_dir(): "; + + unless ( $ENV{$env_home_name} ) { + common_notice( $K . "Umgebungsvariable '" . $env_home_name . "' nicht gesetzt." ); + return undef; + } + + unless ( File::Spec->file_name_is_absolute( $ENV{$env_home_name} ) ) { + common_notice( $K . "Umgebungsvariable '" . $env_home_name . "' (" . $ENV{$env_home_name} . ") ist keine absolute Pfadangabe." ); + return undef; + } + + unless ( -d $ENV{$env_home_name} ) { + common_notice( + $K . "Umgebungsvariable '" . $env_home_name . "' zeigt auf nicht vorhandenes Verzeichnis '" . $ENV{$env_home_name} . "'." ); + return undef; + } + + return File::Spec->canonpath( $ENV{$env_home_name} ); + +} ## end sub home_dir + +#------------------------------------------------------------------------------------------ + +=head2 canon_filename( @directories, $filename ) + +Kettet die uebergebenen Verzeichnisnamen und Dateinamen aneinander. +Wenn der resultierende Pfad nicht absolut ist, wird home_dir() davorgehaengt. + +=cut + +sub canon_filename { + + my @path = @_; + my $K = __PACKAGE__ . "::canon_filename(): "; + + unless ( scalar(@path) ) { + common_notice( $K . "Keine Argumente uebergeben." ); + return undef; + } + + my $file = File::Spec->catfile(@path); + unless ( File::Spec->file_name_is_absolute($file) ) { + my $home = home_dir(); + return undef unless $home; + $file = File::Spec->catfile( $home, @path ); + } + + return $file; + +} ## end sub canon_filename + +#--------------------------------------------------------------------------- + +=head2 common_debug( $debug_level, @messages ) + +Allgemeine Debug-Funktion (wenn das Log-Objekt noch nicht existieren sollte) + +=cut + +sub common_debug { + + my $debug_level = shift; + + $debug_level = to_int($debug_level); + $debug_level = 1 unless defined $debug_level; + + return if $debug_level > $verbose; + + my $text = get_output_string(@_); + return if $text eq ''; + + print $mark . " (debug" . $debug_level . "): " . $text . "\n"; + + return; + +} ## end sub common_debug + +#--------------------------------------------------------------------------- + +sub get_output_string { + + my $text = ''; + for (@_) { + next unless defined $_; + my $t = ref($_) ? Dumper($_) : $_; + next if $t eq ''; + $text .= $t; + } + + $text =~ s/^\s+//; + $text =~ s/\s+$//s; + return $text; + +} ## end sub get_output_string + +#--------------------------------------------------------------------------- + +=head2 common_error( $error_level, @messages ) + +Allgemeine Error-Warn-Funktion (wenn das Log-Objekt noch nicht existieren sollte) + +=cut + +sub common_error { + + my $error_level = shift; + + $error_level ||= 'error'; + + my $text = get_output_string(@_); + + $text = "unbekannter Fehler" if $text eq ''; + + warn $mark . "(" . $error_level . "): " . $text . "\n"; + + return; + +} ## end sub common_error + +#--------------------------------------------------------------------------- + +=head2 common_notice( @messages ) + +Allgemeine Warnmeldung. + +=cut + +sub common_notice { + + my $text = get_output_string(@_); + $text = "unbekannter Fehler" if $text eq ''; + + warn $mark . ": " . $text . "\n"; + + return; + +} ## end sub common_notice + +#------------------------------------------------------------------------------------------ + +=head2 to_bool( $wert ) + +Wandelt den uebergebenen Scalar sicher in einen Wahrheitswert (0 oder 1) um. + +=cut + +sub to_bool { + + my $val = shift; + + return 0 unless defined $val; + return 0 if $val =~ /^\s*$/; + + if ( $val =~ /^\s*y(?:es?)?/i + or $val =~ /^\s*ja?/i + or $val =~ /^\s*[wt]\s*$/i + or $val =~ /^\s*on\s*$/i + or $val =~ /^\s*wahr|true/i ) + { + return 1; + } + + if ( $val =~ /^\s*no?/i + or $val =~ /^\s*ne(?:in?)?/i + or $val =~ /^\s*f\s*$/i + or $val =~ /^\s*off\s*$/i + or $val =~ /^\s*falsch|false/i ) + { + return 0; + } + + my $intval = to_int($val); + if ( defined $intval ) { + return $intval ? 1 : 0; + } + + return $val ? 1 : 0; + +} ## end sub to_bool + +#------------------------------------------------------------------------------------------ + +=head2 to_float( $wert ) + +Wandelt den uebergebenen Scalar sicher in eine Float-Zahl um. + +Falls der uebergebene Wert keine gueltige Zahl ist, wird undef zurueckgegeben. + +=cut + +sub to_float { + + my $val = shift; + + return undef unless defined($val) and $val =~ /\d/; + + my $ts = ","; + my $ds = "."; + + if ( ( $val =~ /\d,/ and $val !~ /\d\./ ) + or ( $val =~ /\d\.\d\d\d\./ ) + or ( $val =~ /\d\.\d\d\d,/ ) ) + { + $ds = ","; + $ts = "."; + } + + $val =~ s/\Q$ts\E//g; + $val =~ s/\Q$ds\E/\./g; + + return ( $val + 0 ); + +} ## end sub to_float + +#------------------------------------------------------------------------------------------ + +=head2 to_int( $wert, $signed ) + +Wandelt den uebergebenen Wert sicher in eine Integer-Zahl um. + +Dabei legt der optionale logische Parameter $signed fest, ob auch +vorzeichenbehaftete Werte zulaessig sind. + +Wenn keine gueltige Zahl uebergeben wird, wird undef zurueckgegeben. + +=cut + +sub to_int { + + my $val = shift; + my $signed = shift; + + return undef unless defined $val; + unless ( $val =~ /\d/ ) { + return undef; + } + + if ($signed) { + $val =~ /^[^\d-]*(?:(-)\s*)?(\d+)/; + $val = ( defined $1 ? $1 : '' ) . $2; + } + else { + $val =~ /^\D*(\d+)/; + $val = $1; + } + + return $val + 0; + +} ## end sub to_int + +#------------------------------------------------------------------------------------------ + +=head2 escape_html( $text ) + +Maskiert alle '&', '<', '>' und '"' im uebergebenen Text durch entsprechende +HTML-Entities. + +Entnommen dem Modul L. + +=cut + +sub escape_html { + + return unless defined( my $toencode = shift ); + + $toencode =~ s{&}{&}gso; + $toencode =~ s{<}{<}gso; + $toencode =~ s{>}{>}gso; + $toencode =~ s{\"}{"}gso; + + # Doesn't work. Can't work. forget it. + # $toencode =~ s{\x8b}{‹}gso; + # $toencode =~ s{\x9b}{›}gso; + + $toencode; + +} ## end sub escape_html + +#------------------------------------------------------------------------------------------ + +1; + +#------------------------------------------------------------------------------------------ + +__END__ diff --git a/lib/CookBook/Common.pm.bak b/lib/CookBook/Common.pm.bak new file mode 100644 index 0000000..27455fb --- /dev/null +++ b/lib/CookBook/Common.pm.bak @@ -0,0 +1,429 @@ +package CookBook::Common; + +# $Id: Common.pm 69 2007-06-27 12:55:47Z fbrehm $ +# $URL: http://maria.technik.berlin.strato.de:8080/svn-cit/trunk/CIT/lib/CIT/Common.pm $ + +=head1 NAME + +CookBook::Common + +=head1 DESCRIPTION + +Modul fuer allgemeine Aufgaben, zum Beispiel Verbose-Level usw. + +Dieses Modul sollte von allen Scripten und Modulen verwendet werden. + +=cut + +#--------------------------------------------------------------------------- + +use strict; +use warnings; +use Exporter; +use Data::Dumper; +use Cwd; +use File::Spec; + +use Carp qw(:DEFAULT cluck); + +our @ISA = qw(Exporter); +our @EXPORT = qw( + &verbose + &canon_filename + &common_debug + &common_error + &common_notice + &get_output_string + &escape_html + &home_dir + &to_bool + &to_float + &to_int +); + +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; + +our $COOKBOOK_VERSION = "1.1"; +our $AUTHOR = 'Frank Brehm '; + +our $env_home_name = 'COOKBOOK_HOME'; + +my $Revis = <<'ENDE'; + $Revision: 69 $ +ENDE +$Revis =~ s/^.*:\s*(\S+)\s*\$.*/$1/s; +our $VERSION = $COOKBOOK_VERSION . "." . $Revis; + +my $verbose = 0; +my $mark = 'CookBook'; + +#------------------------------------------------------------------------------------------ + +=head1 Funktionen + +Alle hier definierten Funktionen werden exportiert. + +#------------------------------------------------------------------------------------------ + +=head2 verbose( $new_verbose_level ) + +Setzt bzw. gibt den Verbose-Level des aktuellen Scripts zurueck. + +Typische Werte: + +=over 4 + +=item I<0>: + +Keinerlei Ausgaben. + +=item I<1>: + +Ausgabe der wichtigsten Aktionen des aktuellen Scripts (sollte eigentlich Standard sein). + +. +. +. + +=item I<6>: + +Ausfuehrlichstes Geplapper bis zum Gehtnichtmehr. + +=back + +=cut + +sub verbose { + + my $new_verbose_level = shift; + + if ( defined $new_verbose_level and $new_verbose_level =~ /^\d+$/ ) { + $verbose = $new_verbose_level; + } + + return $verbose; + +} ## end sub verbose + +##------------------------------------------------------------------------------------------ + +=head2 mark( [$new_mark] ) + +Gibt den aktuellen Log-Marker zurueck bzw. setzt einen neuen, wenn er übergeben wurde. + +=cut + +sub mark { + + my $new_mark = shift; + + if ( $new_mark and $new_mark !~ /^\s*$/ ) { + $new_mark =~ s/^\s+//; + $new_mark =~ s/\s+$//s; + $mark = $new_mark; + } + + return $mark; + +} + +#------------------------------------------------------------------------------------------ + +=head2 home_dir() + +Gibt den Namen des Verzeichnisses der Software-Installation zurueck, +die aus der Umgebungsvariablen C entnommen wird. + +Wenn die Umgebungsvariable nicht gesetzt ist bzw. auf ein nicht vorhandenes Verzeichnis +zeigt, wird undef zurueckgegeben. + +=cut + +sub home_dir { + + my $K = __PACKAGE__ . "::home_dir(): "; + + unless ( $ENV{$env_home_name} ) { + common_notice( $K . "Umgebungsvariable '" . $env_home_name . "' nicht gesetzt." ); + return undef; + } + + unless ( File::Spec->file_name_is_absolute( $ENV{$env_home_name} ) ) { + common_notice( $K . "Umgebungsvariable '" . $env_home_name . "' (" . $ENV{$env_home_name} . ") ist keine absolute Pfadangabe." ); + return undef; + } + + unless ( -d $ENV{$env_home_name} ) { + common_notice( $K . "Umgebungsvariable '" . $env_home_name . "' zeigt auf nicht vorhandenes Verzeichnis '" . $ENV{$env_home_name} . "'." ); + return undef; + } + + return File::Spec->canonpath( $ENV{$env_home_name} ); + +} ## end sub home_dir + +#------------------------------------------------------------------------------------------ + +=head2 canon_filename( @directories, $filename ) + +Kettet die uebergebenen Verzeichnisnamen und Dateinamen aneinander. +Wenn der resultierende Pfad nicht absolut ist, wird home_dir() davorgehaengt. + +=cut + +sub canon_filename { + + my @path = @_; + my $K = __PACKAGE__ . "::canon_filename(): "; + + unless ( scalar(@path) ) { + common_notice( $K . "Keine Argumente uebergeben." ); + return undef; + } + + my $file = File::Spec->catfile(@path); + unless ( File::Spec->file_name_is_absolute($file) ) { + my $home = home_dir(); + return undef unless $home; + $file = File::Spec->catfile( $home, @path ); + } + + return $file; + +} ## end sub canon_filename + +#--------------------------------------------------------------------------- + +=head2 common_debug( $debug_level, @messages ) + +Allgemeine Debug-Funktion (wenn das Log-Objekt noch nicht existieren sollte) + +=cut + +sub common_debug { + + my $debug_level = shift; + + $debug_level = to_int($debug_level); + $debug_level = 1 unless defined $debug_level; + + return if $debug_level > $verbose; + + my $text = get_output_string(@_); + return if $text eq ''; + + print $mark . " (debug" . $debug_level . "): " . $text . "\n"; + + return; + +} ## end sub common_debug + +#--------------------------------------------------------------------------- + +sub get_output_string { + + my $text = ''; + for (@_) { + next unless defined $_; + my $t = ref($_) ? Dumper($_) : $_; + next if $t eq ''; + $text .= $t; + } + + $text =~ s/^\s+//; + $text =~ s/\s+$//s; + return $text; + +} + +#--------------------------------------------------------------------------- + +=head2 common_error( $error_level, @messages ) + +Allgemeine Error-Warn-Funktion (wenn das Log-Objekt noch nicht existieren sollte) + +=cut + +sub common_error { + + my $error_level = shift; + + $error_level ||= 'error'; + + my $text = get_output_string(@_); + + $text = "unbekannter Fehler" if $text eq ''; + + warn $mark . "(" . $error_level . "): " . $text . "\n"; + + return; + +} ## end sub common_error + +#--------------------------------------------------------------------------- + +=head2 common_notice( @messages ) + +Allgemeine Warnmeldung. + +=cut + +sub common_notice { + + my $text = get_output_string(@_); + $text = "unbekannter Fehler" if $text eq ''; + + warn $mark . ": " . $text . "\n"; + + return; + +} ## end sub common_notice + +#------------------------------------------------------------------------------------------ + +=head2 to_bool( $wert ) + +Wandelt den uebergebenen Scalar sicher in einen Wahrheitswert (0 oder 1) um. + +=cut + +sub to_bool { + + my $val = shift; + + return 0 unless defined $val; + return 0 if $val =~ /^\s*$/; + + if ( $val =~ /^\s*y(?:es?)?/i + or $val =~ /^\s*ja?/i + or $val =~ /^\s*[wt]\s*$/i + or $val =~ /^\s*on\s*$/i + or $val =~ /^\s*wahr|true/i ) + { + return 1; + } + + if ( $val =~ /^\s*no?/i + or $val =~ /^\s*ne(?:in?)?/i + or $val =~ /^\s*f\s*$/i + or $val =~ /^\s*off\s*$/i + or $val =~ /^\s*falsch|false/i ) + { + return 0; + } + + my $intval = to_int($val); + if ( defined $intval ) { + return $intval ? 1 : 0; + } + + return $val ? 1 : 0; + +} ## end sub to_bool + +#------------------------------------------------------------------------------------------ + +=head2 to_float( $wert ) + +Wandelt den uebergebenen Scalar sicher in eine Float-Zahl um. + +Falls der uebergebene Wert keine gueltige Zahl ist, wird undef zurueckgegeben. + +=cut + +sub to_float { + + my $val = shift; + + return undef unless defined($val) and $val =~ /\d/; + + my $ts = ","; + my $ds = "."; + + if ( ( $val =~ /\d,/ and $val !~ /\d\./ ) + or ( $val =~ /\d\.\d\d\d\./ ) + or ( $val =~ /\d\.\d\d\d,/ ) ) + { + $ds = ","; + $ts = "."; + } + + $val =~ s/\Q$ts\E//g; + $val =~ s/\Q$ds\E/\./g; + + return ( $val + 0 ); + +} ## end sub to_float + +#------------------------------------------------------------------------------------------ + +=head2 to_int( $wert, $signed ) + +Wandelt den uebergebenen Wert sicher in eine Integer-Zahl um. + +Dabei legt der optionale logische Parameter $signed fest, ob auch +vorzeichenbehaftete Werte zulaessig sind. + +Wenn keine gueltige Zahl uebergeben wird, wird undef zurueckgegeben. + +=cut + +sub to_int { + + my $val = shift; + my $signed = shift; + + return undef unless defined $val; + unless ( $val =~ /\d/ ) { + return undef; + } + + if ($signed) { + $val =~ /^[^\d-]*(?:(-)\s*)?(\d+)/; + $val = ( defined $1 ? $1 : '' ) . $2; + } + else { + $val =~ /^\D*(\d+)/; + $val = $1; + } + + return $val + 0; + +} ## end sub to_int + +#------------------------------------------------------------------------------------------ + +=head2 escape_html( $text ) + +Maskiert alle '&', '<', '>' und '"' im uebergebenen Text durch entsprechende +HTML-Entities. + +Entnommen dem Modul L. + +=cut + +sub escape_html { + + return unless defined( my $toencode = shift ); + + $toencode =~ s{&}{&}gso; + $toencode =~ s{<}{<}gso; + $toencode =~ s{>}{>}gso; + $toencode =~ s{\"}{"}gso; + +# Doesn't work. Can't work. forget it. +# $toencode =~ s{\x8b}{‹}gso; +# $toencode =~ s{\x9b}{›}gso; + + $toencode; + +} + +#------------------------------------------------------------------------------------------ + +1; + +#------------------------------------------------------------------------------------------ + +__END__ diff --git a/lib/CookBook/Controller/Root.pm b/lib/CookBook/Controller/Root.pm new file mode 100644 index 0000000..d6a10e2 --- /dev/null +++ b/lib/CookBook/Controller/Root.pm @@ -0,0 +1,55 @@ +package CookBook::Controller::Root; + +use strict; +use warnings; +use base 'Catalyst::Controller'; + +# +# Sets the actions in this controller to be registered with no prefix +# so they function identically to actions created in MyApp.pm +# +__PACKAGE__->config->{namespace} = ''; + +=head1 NAME + +CookBook::Controller::Root - Root Controller for CookBook + +=head1 DESCRIPTION + +[enter your description here] + +=head1 METHODS + +=cut + +=head2 default + +=cut + +sub default : Private { + my ( $self, $c ) = @_; + + # Hello World + $c->response->body( $c->welcome_message ); +} + +=head2 end + +Attempt to render a view, if needed. + +=cut + +sub end : ActionClass('RenderView') {} + +=head1 AUTHOR + +Frank Brehm + +=head1 LICENSE + +This library is free software, you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +1; diff --git a/root/favicon.ico b/root/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..5ad723dc416e8ad9c8dea9457a564c59499466e9 GIT binary patch literal 2551 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 U;!MG3z7_z~G1jho3XU%Q9~)wzf&c&j literal 0 HcmV?d00001 diff --git a/root/static/images/btn_120x50_powered_shadow.png b/root/static/images/btn_120x50_powered_shadow.png new file mode 100644 index 0000000000000000000000000000000000000000..e6876c08fc78dcad5e4fd5a2e895f3522ad63a13 GIT binary patch literal 3673 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 UbTFT1G^xE3}C@ABzvgNF-{S6H` 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 a0|4eoa7M-5CQbkV002ovPDHLkV1l4dqzaP& literal 0 HcmV?d00001 diff --git a/root/static/images/catalyst_logo.png b/root/static/images/catalyst_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..21f1cac7a9e12236982adf3f548dcaee560cbabb GIT binary patch literal 13710 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 literal 0 HcmV?d00001 diff --git a/script/cookbook_cgi.pl b/script/cookbook_cgi.pl new file mode 100755 index 0000000..f5e6f2a --- /dev/null +++ b/script/cookbook_cgi.pl @@ -0,0 +1,37 @@ +#!/usr/bin/perl -w + +BEGIN { $ENV{CATALYST_ENGINE} ||= 'CGI' } + +use strict; +use warnings; +use FindBin; +use lib "$FindBin::Bin/../lib"; +use CookBook; + +CookBook->run; + +1; + +=head1 NAME + +cookbook_cgi.pl - Catalyst CGI + +=head1 SYNOPSIS + +See L + +=head1 DESCRIPTION + +Run a Catalyst application as a cgi script. + +=head1 AUTHOR + +Sebastian Riedel, C + +=head1 COPYRIGHT + + +This library is free software, you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/script/cookbook_create.pl b/script/cookbook_create.pl new file mode 100755 index 0000000..e45453e --- /dev/null +++ b/script/cookbook_create.pl @@ -0,0 +1,74 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; +use Getopt::Long; +use Pod::Usage; +use Catalyst::Helper; + +my $force = 0; +my $mech = 0; +my $help = 0; + +GetOptions( + 'nonew|force' => \$force, + 'mech|mechanize' => \$mech, + 'help|?' => \$help + ); + +pod2usage(1) if ( $help || !$ARGV[0] ); + +my $helper = Catalyst::Helper->new( { '.newfiles' => !$force, mech => $mech } ); + +pod2usage(1) unless $helper->mk_component( 'CookBook', @ARGV ); + +1; + +=head1 NAME + +cookbook_create.pl - Create a new Catalyst Component + +=head1 SYNOPSIS + +cookbook_create.pl [options] model|view|controller name [helper] [options] + + Options: + -force don't create a .new file where a file to be created exists + -mechanize use Test::WWW::Mechanize::Catalyst for tests if available + -help display this help and exits + + Examples: + cookbook_create.pl controller My::Controller + cookbook_create.pl -mechanize controller My::Controller + cookbook_create.pl view My::View + cookbook_create.pl view MyView TT + cookbook_create.pl view TT TT + cookbook_create.pl model My::Model + cookbook_create.pl model SomeDB DBIC::Schema MyApp::Schema create=dynamic\ + dbi:SQLite:/tmp/my.db + cookbook_create.pl model AnotherDB DBIC::Schema MyApp::Schema create=static\ + dbi:Pg:dbname=foo root 4321 + + See also: + perldoc Catalyst::Manual + perldoc Catalyst::Manual::Intro + +=head1 DESCRIPTION + +Create a new Catalyst Component. + +Existing component files are not overwritten. If any of the component files +to be created already exist the file will be written with a '.new' suffix. +This behavior can be suppressed with the C<-force> option. + +=head1 AUTHOR + +Sebastian Riedel, C +Maintained by the Catalyst Core Team. + +=head1 COPYRIGHT + +This library is free software, you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/script/cookbook_fastcgi.pl b/script/cookbook_fastcgi.pl new file mode 100755 index 0000000..cbd6abc --- /dev/null +++ b/script/cookbook_fastcgi.pl @@ -0,0 +1,80 @@ +#!/usr/bin/perl -w + +BEGIN { $ENV{CATALYST_ENGINE} ||= 'FastCGI' } + +use strict; +use warnings; +use Getopt::Long; +use Pod::Usage; +use FindBin; +use lib "$FindBin::Bin/../lib"; +use CookBook; + +my $help = 0; +my ( $listen, $nproc, $pidfile, $manager, $detach, $keep_stderr ); + +GetOptions( + 'help|?' => \$help, + 'listen|l=s' => \$listen, + 'nproc|n=i' => \$nproc, + 'pidfile|p=s' => \$pidfile, + 'manager|M=s' => \$manager, + 'daemon|d' => \$detach, + 'keeperr|e' => \$keep_stderr, +); + +pod2usage(1) if $help; + +CookBook->run( + $listen, + { nproc => $nproc, + pidfile => $pidfile, + manager => $manager, + detach => $detach, + keep_stderr => $keep_stderr, + } +); + +1; + +=head1 NAME + +cookbook_fastcgi.pl - Catalyst FastCGI + +=head1 SYNOPSIS + +cookbook_fastcgi.pl [options] + + Options: + -? -help display this help and exits + -l -listen Socket path to listen on + (defaults to standard input) + can be HOST:PORT, :PORT or a + filesystem path + -n -nproc specify number of processes to keep + to serve requests (defaults to 1, + requires -listen) + -p -pidfile specify filename for pid file + (requires -listen) + -d -daemon daemonize (requires -listen) + -M -manager specify alternate process manager + (FCGI::ProcManager sub-class) + or empty string to disable + -e -keeperr send error messages to STDOUT, not + to the webserver + +=head1 DESCRIPTION + +Run a Catalyst application as fastcgi. + +=head1 AUTHOR + +Sebastian Riedel, C +Maintained by the Catalyst Core Team. + +=head1 COPYRIGHT + +This library is free software, you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/script/cookbook_server.pl b/script/cookbook_server.pl new file mode 100755 index 0000000..912e3ea --- /dev/null +++ b/script/cookbook_server.pl @@ -0,0 +1,111 @@ +#!/usr/bin/perl -w + +BEGIN { + $ENV{CATALYST_ENGINE} ||= 'HTTP'; + $ENV{CATALYST_SCRIPT_GEN} = 30; + require Catalyst::Engine::HTTP; +} + +use strict; +use warnings; +use Getopt::Long; +use Pod::Usage; +use FindBin; +use lib "$FindBin::Bin/../lib"; + +my $debug = 0; +my $fork = 0; +my $help = 0; +my $host = undef; +my $port = 3000; +my $keepalive = 0; +my $restart = 0; +my $restart_delay = 1; +my $restart_regex = '\.yml$|\.yaml$|\.pm$'; +my $restart_directory = undef; + +my @argv = @ARGV; + +GetOptions( + 'debug|d' => \$debug, + 'fork' => \$fork, + 'help|?' => \$help, + 'host=s' => \$host, + 'port=s' => \$port, + 'keepalive|k' => \$keepalive, + 'restart|r' => \$restart, + 'restartdelay|rd=s' => \$restart_delay, + 'restartregex|rr=s' => \$restart_regex, + 'restartdirectory=s' => \$restart_directory, +); + +pod2usage(1) if $help; + +if ( $restart ) { + $ENV{CATALYST_ENGINE} = 'HTTP::Restarter'; +} +if ( $debug ) { + $ENV{CATALYST_DEBUG} = 1; +} + +# This is require instead of use so that the above environment +# variables can be set at runtime. +require CookBook; + +CookBook->run( $port, $host, { + argv => \@argv, + 'fork' => $fork, + keepalive => $keepalive, + restart => $restart, + restart_delay => $restart_delay, + restart_regex => qr/$restart_regex/, + restart_directory => $restart_directory, +} ); + +1; + +=head1 NAME + +cookbook_server.pl - Catalyst Testserver + +=head1 SYNOPSIS + +cookbook_server.pl [options] + + Options: + -d -debug force debug mode + -f -fork handle each request in a new process + (defaults to false) + -? -help display this help and exits + -host host (defaults to all) + -p -port port (defaults to 3000) + -k -keepalive enable keep-alive connections + -r -restart restart when files get modified + (defaults to false) + -rd -restartdelay delay between file checks + -rr -restartregex regex match files that trigger + a restart when modified + (defaults to '\.yml$|\.yaml$|\.pm$') + -restartdirectory the directory to search for + modified files + (defaults to '../') + + See also: + perldoc Catalyst::Manual + perldoc Catalyst::Manual::Intro + +=head1 DESCRIPTION + +Run a Catalyst Testserver for this application. + +=head1 AUTHOR + +Sebastian Riedel, C +Maintained by the Catalyst Core Team. + +=head1 COPYRIGHT + +This library is free software, you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/script/cookbook_test.pl b/script/cookbook_test.pl new file mode 100755 index 0000000..240cb66 --- /dev/null +++ b/script/cookbook_test.pl @@ -0,0 +1,54 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; +use Getopt::Long; +use Pod::Usage; +use FindBin; +use lib "$FindBin::Bin/../lib"; +use Catalyst::Test 'CookBook'; + +my $help = 0; + +GetOptions( 'help|?' => \$help ); + +pod2usage(1) if ( $help || !$ARGV[0] ); + +print request($ARGV[0])->content . "\n"; + +1; + +=head1 NAME + +cookbook_test.pl - Catalyst Test + +=head1 SYNOPSIS + +cookbook_test.pl [options] uri + + Options: + -help display this help and exits + + Examples: + cookbook_test.pl http://localhost/some_action + cookbook_test.pl /some_action + + See also: + perldoc Catalyst::Manual + perldoc Catalyst::Manual::Intro + +=head1 DESCRIPTION + +Run a Catalyst action from the command line. + +=head1 AUTHOR + +Sebastian Riedel, C +Maintained by the Catalyst Core Team. + +=head1 COPYRIGHT + +This library is free software, you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/t/01app.t b/t/01app.t new file mode 100644 index 0000000..d9a3619 --- /dev/null +++ b/t/01app.t @@ -0,0 +1,7 @@ +use strict; +use warnings; +use Test::More tests => 2; + +BEGIN { use_ok 'Catalyst::Test', 'CookBook' } + +ok( request('/')->is_success, 'Request should succeed' ); diff --git a/t/02pod.t b/t/02pod.t new file mode 100644 index 0000000..251640d --- /dev/null +++ b/t/02pod.t @@ -0,0 +1,9 @@ +use strict; +use warnings; +use Test::More; + +eval "use Test::Pod 1.14"; +plan skip_all => 'Test::Pod 1.14 required' if $@; +plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD}; + +all_pod_files_ok(); diff --git a/t/03podcoverage.t b/t/03podcoverage.t new file mode 100644 index 0000000..ae59d4c --- /dev/null +++ b/t/03podcoverage.t @@ -0,0 +1,9 @@ +use strict; +use warnings; +use Test::More; + +eval "use Test::Pod::Coverage 1.04"; +plan skip_all => 'Test::Pod::Coverage 1.04 required' if $@; +plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD}; + +all_pod_coverage_ok(); -- 2.39.5