You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(381) |
Nov
(176) |
Dec
(310) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(334) |
Feb
(96) |
Mar
(149) |
Apr
(214) |
May
(120) |
Jun
(56) |
Jul
(10) |
Aug
(273) |
Sep
(182) |
Oct
(56) |
Nov
(125) |
Dec
(22) |
2003 |
Jan
(63) |
Feb
(181) |
Mar
(498) |
Apr
(433) |
May
(39) |
Jun
(512) |
Jul
(276) |
Aug
(156) |
Sep
(101) |
Oct
(66) |
Nov
(24) |
Dec
(161) |
2004 |
Jan
(1) |
Feb
(377) |
Mar
(68) |
Apr
(26) |
May
(107) |
Jun
(333) |
Jul
(13) |
Aug
|
Sep
(76) |
Oct
(88) |
Nov
(170) |
Dec
(91) |
2005 |
Jan
(52) |
Feb
(239) |
Mar
(402) |
Apr
(15) |
May
(2) |
Jun
(1) |
Jul
(13) |
Aug
|
Sep
(71) |
Oct
(34) |
Nov
|
Dec
|
2006 |
Jan
(5) |
Feb
(5) |
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(3) |
Sep
(7) |
Oct
(2) |
Nov
|
Dec
|
2007 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Chris W. <la...@us...> - 2005-02-25 05:38:20
|
Update of /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2/Setup In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24331/Setup Modified Files: InitializeControllers.pm Log Message: add pointer to observable Index: InitializeControllers.pm =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2/Setup/InitializeControllers.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** InitializeControllers.pm 13 Feb 2005 20:25:44 -0000 1.2 --- InitializeControllers.pm 25 Feb 2005 05:38:07 -0000 1.3 *************** *** 70,73 **** --- 70,75 ---- L<OpenInteract2::Setup> + L<Class::Observable> + =head1 COPYRIGHT |
From: Chris W. <la...@us...> - 2005-02-25 05:38:12
|
Update of /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24219 Modified Files: Request.pm Log Message: rename find_language() to assign_languages(), and document; get rid of the custom language class thing (yuck) Index: Request.pm =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2/Request.pm,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -d -r1.51 -r1.52 *** Request.pm 17 Feb 2005 05:01:55 -0000 1.51 --- Request.pm 25 Feb 2005 05:37:45 -0000 1.52 *************** *** 348,353 **** } ! sub find_language { ! my ( $self ) = @_; my @lang = (); my $lang_config = CTX->lookup_language_config; --- 348,361 ---- } ! sub assign_languages { ! my ( $self, @assigned ) = @_; ! if ( scalar @assigned ) { ! delete $self->{_lang_handle}; # clear out cache ! $self->{_user_language} = \@assigned; ! $log->is_debug && ! $log->debug( "Request property 'language' assigned to: ", ! join( ', ', @assigned ) ); ! return; ! } my @lang = (); my $lang_config = CTX->lookup_language_config; *************** *** 384,393 **** } ! if ( my @clubber_lang = $self->_find_custom_languages( @lang ) ) { ! $self->{_user_language} = \@clubber_lang; ! } ! else { ! $self->{_user_language} = \@lang; ! } $log->is_debug && $log->debug( "Request property 'language' now: ", --- 392,396 ---- } ! $self->{_user_language} = \@lang; $log->is_debug && $log->debug( "Request property 'language' now: ", *************** *** 419,444 **** } - sub _find_custom_languages { - my ( $self, @oi_lang ) = @_; - my $lang_info = CTX->lookup_language_config; - return unless ( $lang_info->{custom_language_id_class} ); - $log ||= get_logger( LOG_REQUEST ); - - my $lang_class = $lang_info->{custom_language_id_class}; - $log->is_debug && - $log->debug( "Running custom lang ID class '$lang_class'" ); - my @new_langs = eval { - $lang_class->identify_languages( @oi_lang ) - }; - if ( $@ ) { - $log->error( "Failed to get custom languages from ", - "'$lang_class': $@" ); - return (); - } - else { - return @new_langs; - } - } - sub language_handle { my ( $self ) = @_; --- 422,425 ---- *************** *** 706,709 **** --- 687,724 ---- localized messages. + B<assign_languages( [ @assigned ] )> + + Typically called only by an adapter or the authentication classes + which use the default behavior described below. But you can also + assign languages directly to the request object with this: + + $request->assign_languages( 'en', 'jp', 'sv' ); + + If you do assign languages directly any language handle previously + cached for the request is removed. + + Otherwise we find the language from one of: + + =over 4 + + =item * + + the user (if logged in) + + =item * + + session (from 'language' key); + + =item * + + parameter value (listed in server configuration of + 'language.choice_param_name'; + + =item * + + or default language set in 'language.default_language'. + + =back + =head2 Properties |
From: Chris W. <la...@us...> - 2005-02-25 05:37:18
|
Update of /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24119 Modified Files: Auth.pm Log Message: rename find_language() method from OI2::Request Index: Auth.pm =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2/Auth.pm,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** Auth.pm 5 Oct 2004 01:27:51 -0000 1.20 --- Auth.pm 25 Feb 2005 05:37:09 -0000 1.21 *************** *** 93,97 **** # ...and load the languages ! $request->find_language; unless ( ref $self->groups eq 'ARRAY' ) { --- 93,97 ---- # ...and load the languages ! $request->assign_languages; unless ( ref $self->groups eq 'ARRAY' ) { |
From: Chris W. <la...@us...> - 2005-02-25 05:37:05
|
Update of /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23995 Modified Files: ActionResolver.pm Log Message: doc updates -- discard the stuff about side-effects and show how to actually do it Index: ActionResolver.pm =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2/ActionResolver.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ActionResolver.pm 13 Feb 2005 20:37:35 -0000 1.1 --- ActionResolver.pm 25 Feb 2005 05:36:38 -0000 1.2 *************** *** 122,126 **** aren't given we use the result from our C<get_all_resolvers()> class method. Each of the L<OpenInteract2::ActionResolver> objects in ! C<@resolvers> will get called and asked if it can resolve C<$url> This will either return an L<OpenInteract2::Action> object or throw an --- 122,126 ---- aren't given we use the result from our C<get_all_resolvers()> class method. Each of the L<OpenInteract2::ActionResolver> objects in ! C<@resolvers> will get called and asked if it can resolve C<$url>. This will either return an L<OpenInteract2::Action> object or throw an *************** *** 152,161 **** should get executed. ! The object may also create side-effects along the way. For instance, ! one of the built-in resolvers finds a parameter 'oi_language' from ! C<$request> and if it exists assigns that language for the ! request. (Yes, this technically isn't resolving an action, but there's ! no real use to create B<another> set of classes that perform such a ! similar action.) =head1 SEE ALSO --- 152,179 ---- should get executed. ! If you're thinking of implementing an this class to create a ! side-effect (like looking for a 'my_language' request parameter and ! using that for the language assigned), don't. There's a better ! way. Just create an observer in the ! C<OpenInteract2::Observer::Controller> namespace and we'll pick it up ! automatically from L<OpenInteract2::Setup::InitializeControllers>. The ! observation you're looking for is 'action assigned'. ! ! So to do the above you'd create: ! ! package OpenInteract2::Observer::Controller::Language; ! ! use strict; ! use OpenInteract2::Context qw( CTX ); ! ! sub update { ! my ( $class, $controller, $observation, $action ) = @_; ! return unless ( $observation eq 'action assigned' ); ! my $request = CTX->request; ! my $lang = $request->param( 'my_language' ); ! if ( $lang ) { ! $request->find_languages( $lang, $request->language ); ! } ! } =head1 SEE ALSO |
From: Chris W. <la...@us...> - 2005-02-25 05:36:26
|
Update of /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23782 Modified Files: Context.pm Log Message: allow 'create_date()' to take a 'last_day_of_month' parameter to use that constructor instead of 'new()' Index: Context.pm =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2/Context.pm,v retrieving revision 1.84 retrieving revision 1.85 diff -C2 -d -r1.84 -r1.85 *** Context.pm 19 Feb 2005 04:26:04 -0000 1.84 --- Context.pm 25 Feb 2005 05:35:59 -0000 1.85 *************** *** 286,299 **** my ( $self, $params ) = @_; $params ||= {}; ! if ( $params->{year} ) { ! return DateTime->new( time_zone => $self->timezone_object, ! %{ $params } ); } ! elsif ( $params->{epoch} ) { ! return DateTime->from_epoch( time_zone => $self->timezone_object, ! epoch => $params->{epoch}, ); } --- 286,306 ---- my ( $self, $params ) = @_; $params ||= {}; ! if ( $params->{epoch} ) { ! return DateTime->from_epoch( time_zone => $self->timezone_object, ! epoch => $params->{epoch}, ); } ! elsif ( $params->{last_day_of_month} ) { ! delete $params->{last_day_of_month}; ! return DateTime->last_day_of_month( time_zone => $self->timezone_object, ! %{ $params }, ! ); ! } ! elsif ( $params->{year} ) { ! return DateTime->new( ! time_zone => $self->timezone_object, ! %{ $params } ); } *************** *** 1064,1069 **** and call the L<DateTime> C<now()> method. ! The exception: when you specify 'epoch' in C<\%params> we call the ! C<from_epoch()> method instead of the constructor. This is just a shortcut method and you instead may want to get the --- 1071,1089 ---- and call the L<DateTime> C<now()> method. ! The exceptions: ! ! =over 4 ! ! =item * ! ! when you specify 'epoch' in C<\%params> we call the C<from_epoch()> ! constructorinstead of C<new()>. ! ! =item * ! ! when you specify 'last_day_of_month' in C<\%params> we call the ! C<last_day_of_month()> constructor instead of C<new()>. ! ! =back This is just a shortcut method and you instead may want to get the |
From: Chris W. <la...@us...> - 2005-02-25 05:35:28
|
Update of /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23583 Modified Files: ErrorStorage.pm Log Message: OIN-35: various fixes, mostly small Index: ErrorStorage.pm =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2/ErrorStorage.pm,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ErrorStorage.pm 25 Feb 2005 00:07:19 -0000 1.1 --- ErrorStorage.pm 25 Feb 2005 05:35:16 -0000 1.2 *************** *** 170,179 **** my $year = $date_info{year} || $now->year(); my $month = $date_info{month} || $now->month(); ! my $start = DateTime->new( year => $year, month => $month, day => 1 ); ! my $end = DateTime->last_day_of_month( year => $year, month => $month ); my @all_days = $self->_generate_range( 'days', $start, $end ); my %bd = (); foreach my $dt ( @all_days ) { next if ( $dt > $now ); $bd{ $dt->strftime( '%d' ) } = $self->count_errors( $dt ); } --- 170,185 ---- my $year = $date_info{year} || $now->year(); my $month = $date_info{month} || $now->month(); ! my $start = CTX->create_date({ ! year => $year, month => $month, day => 1 ! }); ! my $end = CTX->create_date({ ! last_day_of_month => 1, year => $year, month => $month ! }); my @all_days = $self->_generate_range( 'days', $start, $end ); + $log->info( "Got ", scalar( @all_days ), "days in range" ); my %bd = (); foreach my $dt ( @all_days ) { next if ( $dt > $now ); + $log->info( "Counting errors for: ", $dt->ymd ); $bd{ $dt->strftime( '%d' ) } = $self->count_errors( $dt ); } *************** *** 188,192 **** } my ( $year, $month, $day ) = split /\D/, $date_spec; - my $count = 0; my @days = (); if ( $day ) { --- 194,197 ---- *************** *** 196,199 **** --- 201,205 ---- push @days, $self->_get_error_days_in_month( "$year-$month" ); } + my $count = 0; foreach my $day ( @days ) { my $dt = $PARSER->parse_datetime( "$year-$month-$day" ); *************** *** 209,215 **** opendir( MON, $month_dir ) || oi_error "Cannot open '$month_dir' for reading: $!"; ! my @days = grep /^\d+/, grep { -d $_ } readdir( MON ); closedir( MON ); ! return @days; } --- 215,221 ---- opendir( MON, $month_dir ) || oi_error "Cannot open '$month_dir' for reading: $!"; ! my @days = grep /^\d+/, grep { -d "$month_dir/$_" } readdir( MON ); closedir( MON ); ! return sort { $b <=> $a } @days; } *************** *** 217,224 **** my ( $self, $dt ) = @_; my $day_dir = $self->_dirname_from_date( $dt ); return 0 unless ( -d $day_dir ); opendir( ERR, $day_dir ) || oi_error "Cannot open '$day_dir' for reading: $!"; ! my @errors = grep /\.txt$/, grep { -f $_ } readdir( ERR ); closedir( ERR ); return scalar @errors; --- 223,231 ---- my ( $self, $dt ) = @_; my $day_dir = $self->_dirname_from_date( $dt ); + $log->info( "Trying to count errors in '$day_dir'" ); return 0 unless ( -d $day_dir ); opendir( ERR, $day_dir ) || oi_error "Cannot open '$day_dir' for reading: $!"; ! my @errors = grep /\.txt$/, grep { -f "$day_dir/$_" } readdir( ERR ); closedir( ERR ); return scalar @errors; *************** *** 273,279 **** if ( blessed( $end_range ) ) { # treat as DateTime my $duration = $end_range - $start; ! $span = $duration->$type(); # e.g., $duration->days(); ! warn "Duration between '", $end_range->strftime( '%F %T' ), "' and", ! "'", $start->strftime( '%F %T' ), "' is $span $type"; } else { --- 280,285 ---- if ( blessed( $end_range ) ) { # treat as DateTime my $duration = $end_range - $start; ! my $method = "delta_$type"; ! $span = $duration->$method(); # e.g., $duration->delta_days(); } else { |
From: Chris W. <la...@us...> - 2005-02-25 05:32:59
|
Update of /cvsroot/openinteract/OpenInteract2/t In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23075 Modified Files: manage_list_objects.t manage_list_actions.t context.t Log Message: fix tests that broke due to removing 'error_filter' action, renaming 'error' action to 'error_browser', and removing 'error' SPOPS object Index: manage_list_objects.t =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/t/manage_list_objects.t,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** manage_list_objects.t 6 Jun 2004 06:36:03 -0000 1.6 --- manage_list_objects.t 25 Feb 2005 05:32:48 -0000 1.7 *************** *** 6,10 **** use lib 't/'; require 'utils.pl'; ! use Test::More tests => 43; require_ok( 'OpenInteract2::Manage' ); --- 6,10 ---- use lib 't/'; require 'utils.pl'; ! use Test::More tests => 41; require_ok( 'OpenInteract2::Manage' ); *************** *** 23,36 **** my @status = eval { $task->execute }; ok( ! $@, 'Task executed ok' ); ! is( scalar @status, 19, 'Correct number of SPOPS objects listed' ); my @names = qw( ! comment comment_notify comment_summary content_type error_object full_text_mapping group news news_section object_action page page_content page_directory security theme themeprop user user_language whats_new ); my @classes = map { "OpenInteract2::$_" } qw( ! Comment CommentNotify CommentSummary ContentType ErrorObject FullTextMapping Group News NewsSection ObjectAction Page PageContent PageDirectory Security Theme ThemeProp User UserLanguage WhatsNew --- 23,36 ---- my @status = eval { $task->execute }; ok( ! $@, 'Task executed ok' ); ! is( scalar @status, 18, 'Correct number of SPOPS objects listed' ); my @names = qw( ! comment comment_notify comment_summary content_type full_text_mapping group news news_section object_action page page_content page_directory security theme themeprop user user_language whats_new ); my @classes = map { "OpenInteract2::$_" } qw( ! Comment CommentNotify CommentSummary ContentType FullTextMapping Group News NewsSection ObjectAction Page PageContent PageDirectory Security Theme ThemeProp User UserLanguage WhatsNew Index: manage_list_actions.t =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/t/manage_list_actions.t,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** manage_list_actions.t 6 Jun 2004 06:36:03 -0000 1.7 --- manage_list_actions.t 25 Feb 2005 05:32:48 -0000 1.8 *************** *** 6,10 **** use lib 't/'; require 'utils.pl'; ! use Test::More tests => 49; require_ok( 'OpenInteract2::Manage' ); --- 6,10 ---- use lib 't/'; require 'utils.pl'; ! use Test::More tests => 48; require_ok( 'OpenInteract2::Manage' ); *************** *** 26,30 **** my @names = qw( admin_tools_box boxes comment comment_recent content_type ! edit_document_box error error_filter file_index forgotpassword group latest_news login_box logout lookups new new_comment_form news news_section news_tools_box newuser --- 26,30 ---- my @names = qw( admin_tools_box boxes comment comment_recent content_type ! edit_document_box error_browser file_index forgotpassword group latest_news login_box logout lookups new new_comment_form news news_section news_tools_box newuser Index: context.t =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/t/context.t,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** context.t 28 Nov 2004 04:49:22 -0000 1.41 --- context.t 25 Feb 2005 05:32:48 -0000 1.42 *************** *** 17,21 **** } ! plan tests => 153; require_ok( 'OpenInteract2::Context' ); --- 17,21 ---- } ! plan tests => 152; require_ok( 'OpenInteract2::Context' ); *************** *** 81,85 **** is( ref $action_table, 'HASH', 'Action table is correct data structure' ); ! is( scalar keys %{ $action_table }, 44, 'Correct number of actions in table' ); --- 81,85 ---- is( ref $action_table, 'HASH', 'Action table is correct data structure' ); ! is( scalar keys %{ $action_table }, 43, 'Correct number of actions in table' ); *************** *** 157,165 **** is( ref $spops_config, 'HASH', 'SPOPS config is correct data structure' ); ! is( scalar keys %{ $spops_config }, 19, 'Correct number of SPOPS configs in structure' ); - is( $ctx->lookup_object( 'error_object' ), 'OpenInteract2::ErrorObject', - 'SPOPS error lookup matched' ); is( $ctx->lookup_object( 'group' ), 'OpenInteract2::Group', 'SPOPS group lookup matched' ); --- 157,163 ---- is( ref $spops_config, 'HASH', 'SPOPS config is correct data structure' ); ! is( scalar keys %{ $spops_config }, 18, 'Correct number of SPOPS configs in structure' ); is( $ctx->lookup_object( 'group' ), 'OpenInteract2::Group', 'SPOPS group lookup matched' ); |
From: Chris W. <la...@us...> - 2005-02-25 05:29:37
|
Update of /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22487 Modified Files: SQLInstall.pm Log Message: get rid of undef warning Index: SQLInstall.pm =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2/SQLInstall.pm,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** SQLInstall.pm 24 Jan 2005 17:12:41 -0000 1.25 --- SQLInstall.pm 25 Feb 2005 05:29:13 -0000 1.26 *************** *** 127,130 **** --- 127,131 ---- sub _set_state { my ( $self, $file, $status, $error, $statement ) = @_; + $file ||= ''; $self->{_status}{ $file } = $status; $self->{_error}{ $file } = $error; |
From: Chris W. <la...@us...> - 2005-02-25 05:21:25
|
Update of /cvsroot/openinteract/OpenInteract2/t In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20717 Modified Files: utils.pl Log Message: update base_error version Index: utils.pl =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/t/utils.pl,v retrieving revision 1.91 retrieving revision 1.92 diff -C2 -d -r1.91 -r1.92 *** utils.pl 25 Feb 2005 00:12:25 -0000 1.91 --- utils.pl 25 Feb 2005 05:21:16 -0000 1.92 *************** *** 47,51 **** base => '2.12', base_box => '2.17', ! base_error => '2.10', base_group => '2.16', base_page => '2.28', --- 47,51 ---- base => '2.12', base_box => '2.17', ! base_error => '3.00', base_group => '2.16', base_page => '2.28', |
From: Chris W. <la...@us...> - 2005-02-25 05:21:08
|
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_error In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20433 Modified Files: package.conf MANIFEST Changes Log Message: OIN-35: update metadata, including bumping up package version to 3.0 Index: package.conf =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/pkg/base_error/package.conf,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** package.conf 19 Feb 2004 14:49:09 -0000 1.11 --- package.conf 25 Feb 2005 05:20:39 -0000 1.12 *************** *** 1,7 **** name base_error ! version 2.10 author Chris Winters (ch...@cw...) url http://www.openinteract.org/ - module Text::Wrap sql_installer OpenInteract2::SQLInstall::Error description --- 1,6 ---- name base_error ! version 3.00 author Chris Winters (ch...@cw...) url http://www.openinteract.org/ sql_installer OpenInteract2::SQLInstall::Error description Index: MANIFEST =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/pkg/base_error/MANIFEST,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** MANIFEST 2 Apr 2003 12:30:40 -0000 1.3 --- MANIFEST 25 Feb 2005 05:20:39 -0000 1.4 *************** *** 1,19 **** Changes MANIFEST - MANIFEST.SKIP package.conf conf/action.ini - conf/spops_error_object.ini data/install_security.dat doc/base_error.pod ! OpenInteract2/ErrorObject.pm ! OpenInteract2/SQLInstall/Error.pm OpenInteract2/Action/Error.pm ! struct/sys_error.sql ! struct/sys_error_interbase.sql ! struct/sys_error_oracle.sql ! template/error_detail.tmpl ! template/error_filter.tmpl ! template/error_list.tmpl ! template/error_search_form.tmpl ! template/error_search_results.tmpl \ No newline at end of file --- 1,14 ---- Changes MANIFEST package.conf conf/action.ini data/install_security.dat doc/base_error.pod ! msg/base_error_messages-en.msg OpenInteract2/Action/Error.pm ! OpenInteract2/SQLInstall/Error.pm ! template/daily_list.tmpl ! template/detail.tmpl ! template/home.tmpl ! template/list.tmpl ! template/monthly_count.tmpl Index: Changes =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/pkg/base_error/Changes,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Changes 19 Feb 2004 14:49:08 -0000 1.12 --- Changes 25 Feb 2005 05:20:39 -0000 1.13 *************** *** 1,9 **** Revision history for OpenInteract package base_error. 2.10 Thu Feb 19 09:51:38 EST 2004 Modify the 'message' field to be 'err_message' ('message' is a ! reserved word in t-sql) and add field_map to the SPOPS object so ! that referencing 'message' still works. 2.09 ... no label! --- 1,14 ---- Revision history for OpenInteract package base_error. + 3.00 Wed Feb 23 22:00:46 EST 2005 + + OIN-35: Revamp package to store errors in filesystem instead of + database. (Initial version with lots of small iterations....) + 2.10 Thu Feb 19 09:51:38 EST 2004 Modify the 'message' field to be 'err_message' ('message' is a ! reserved word in t-sql) and add field_map to the SPOPS object ! so that referencing 'message' still works. 2.09 ... no label! *************** *** 13,18 **** 2.08 Wed Nov 19 23:23:52 EST 2003 ! OI2::ErrorObject subclasses persistence implementation generated ! by SPOPS. 2.07 Mon Oct 13 19:12:21 EDT 2003 --- 18,23 ---- 2.08 Wed Nov 19 23:23:52 EST 2003 ! OI2::ErrorObject subclasses persistence implementation ! generated by SPOPS. 2.07 Mon Oct 13 19:12:21 EDT 2003 *************** *** 30,35 **** 2.04 Fri Jun 27 02:20:19 EDT 2003 ! Changed schema of sys_error table and matched it with action and ! template changes. 2.03 Wed Jun 25 10:29:24 EDT 2003 --- 35,40 ---- 2.04 Fri Jun 27 02:20:19 EDT 2003 ! Changed schema of sys_error table and matched it with action ! and template changes. 2.03 Wed Jun 25 10:29:24 EDT 2003 *************** *** 73,77 **** 1.40 Mon Apr 1 21:17:36 EST 2002 ! Add Oracle-specific tables; rename structure files to match table names. 1.39 Tue Jan 15 17:24:15 EST 2002 --- 78,83 ---- 1.40 Mon Apr 1 21:17:36 EST 2002 ! Add Oracle-specific tables; rename structure files to match ! table names. 1.39 Tue Jan 15 17:24:15 EST 2002 *************** *** 91,95 **** 1.35 Wed Nov 28 00:41:23 EST 2001 ! Fixed the default action for the error handler to be 'search_form'. 1.34 Tue Oct 23 23:20:40 EDT 2001 --- 97,102 ---- 1.35 Wed Nov 28 00:41:23 EST 2001 ! Fixed the default action for the error handler to be ! 'search_form'. 1.34 Tue Oct 23 23:20:40 EDT 2001 *************** *** 98,102 **** OI::CommonHandler, which included rewriting ALL the templates, and adding several new ones. Also rewrote OI/Handler/Error.pm. - - Moved error message templates to main template directory (where the widgets are); --- 105,108 ---- *************** *** 129,133 **** 1.28 Mon Aug 13 12:12:37 EDT 2001 ! Changed all relevant templates to new template format (using OI.blah) 1.27 Mon Aug 13 11:26:12 EDT 2001 --- 135,140 ---- 1.28 Mon Aug 13 12:12:37 EDT 2001 ! Changed all relevant templates to new template format (using ! OI.blah) 1.27 Mon Aug 13 11:26:12 EDT 2001 *************** *** 153,157 **** 1.23 Mon Jul 23 17:04:56 EDT 2001 ! Update so that the object_keys table isn't loaded with new entries. 1.22 Fri Jul 13 00:17:14 EDT 2001 --- 160,165 ---- 1.23 Mon Jul 23 17:04:56 EDT 2001 ! Update so that the object_keys table isn't loaded with new ! entries. 1.22 Fri Jul 13 00:17:14 EDT 2001 *************** *** 180,185 **** 1.17 Tue May 29 23:31:36 EDT 2001 ! Changed all relevant '$R->scrib( ... )' calls to ! '$R->DEBUG && $R->scrib( ... )' 1.16 Tue Mar 13 07:20:31 EST 2001 --- 188,193 ---- 1.17 Tue May 29 23:31:36 EDT 2001 ! Changed all relevant '$R->scrib( ... )' calls to '$R->DEBUG && ! $R->scrib( ... )' 1.16 Tue Mar 13 07:20:31 EST 2001 *************** *** 209,212 **** 1.10 Sun Nov 26 13:53:32 EST 2000 ! Fixed template/error_detail.tmpl to refer to 'action' instead of ! 'module' (label and object property). --- 217,221 ---- 1.10 Sun Nov 26 13:53:32 EST 2000 ! Fixed template/error_detail.tmpl to refer to 'action' instead ! of 'module' (label and object property). ! |
From: Chris W. <la...@us...> - 2005-02-25 05:19:45
|
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_error/doc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20137/doc Modified Files: base_error.pod Log Message: OIN-35: a few words about the new stuff Index: base_error.pod =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/pkg/base_error/doc/base_error.pod,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** base_error.pod 5 Sep 2003 13:57:44 -0000 1.3 --- base_error.pod 25 Feb 2005 05:19:36 -0000 1.4 *************** *** 5,32 **** =head1 DESCRIPTION ! See ! L<OpenInteract2::Manual::ErrorHandling|OpenInteract2::Manual::ErrorHandling> ! for more information about error handling in the OpenInteract2 ! framework. =head1 OBJECTS ! B<error_object> ! ! Represents an error as stored in the database. It has information ! about the error itself, the location whence it was thrown, who was ! logged in when it was thrown and more. =head1 ACTIONS ! B<error> ! ! Main action with the means to display a listing of errors and to drill ! down into a specific error for details. ! ! B<error_filter> ! Template action for displaying the error filter -- form with dates, ! types, codes, etc. =head1 RULESETS --- 5,24 ---- =head1 DESCRIPTION ! Simple package that serializes error objects/data (generally those ! getting to L<OpenInteract2::Log::OIAppender>) to the filesystem. The ! files are organized in a simple date layout -- see ! L<OpenInteract2::ErrorStorage> for more information. =head1 OBJECTS ! None. =head1 ACTIONS ! B<error_browser> ! Main action with the means to display a listing of recent errors, ! browse errors by date, and to drill down into a specific error for ! details. =head1 RULESETS |
From: Chris W. <la...@us...> - 2005-02-25 05:17:46
|
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_error/template In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19746/template Added Files: daily_list.tmpl detail.tmpl home.tmpl list.tmpl monthly_count.tmpl Log Message: OIN-35: add all new templtes --- NEW FILE: daily_list.tmpl --- [%- title = MSG( 'base_error.daily.title', year, month, day ); OI.page_title( title ); -%] <h2>[% title %]</h2> <p>[% MSG( 'base_error.daily.summary', year, month, day, num_errors ) %]</p> <div align="center"> [% INCLUDE base_error::list %] </div> --- NEW FILE: detail.tmpl --- [%- title = MSG( 'base_error.detail.title' ); OI.page_title( title ); -%] [%- PROCESS error_message -%] <h2>[% title %]</h2> [%- INCLUDE table_bordered_begin -%] [%- count = 0; valign = 'top' -%] [%- count = count + 1 -%] [% INCLUDE label_text_row( label_key = 'base_error.time', text = OI.date_format( an_error.time ) ) -%] [%- count = count + 1 -%] [% INCLUDE label_text_row( label_key = 'base_error.message', text = an_error.message ) -%] [%- count = count + 1 -%] [% INCLUDE label_text_row( label_key = 'base_error.category', text = an_error.category ) -%] [%- count = count + 1 -%] [% INCLUDE label_text_row( label_key = 'base_error.location', text = "$an_error.class ($an_error.line)" ) -%] [%- count = count + 1 -%] [% INCLUDE label_text_row( label_key = 'base_error.host', text = an_error.host || 'n/a' ) -%] [%- count = count + 1 -%] [% INCLUDE label_text_row( label_key = 'base_error.user', text = an_error.username || 'n/a' ) -%] [%- count = count + 1 -%] [% INCLUDE label_text_row( label_key = 'base_error.session', text = an_error.session || '(no session tracked)' ) -%] [%- count = count + 1 -%] [% INCLUDE label_text_row( label_key = 'base_error.url', text = an_error.url ) -%] [%- count = count + 1 -%] [% INCLUDE label_text_row( label_key = 'base_error.browser', text = an_error.browser ) -%] [%- count = count + 1 -%] [% INCLUDE label_text_row( label_key = 'base_error.referer', text = an_error.referer ) -%] [% PROCESS table_bordered_end -%] --- NEW FILE: home.tmpl --- [%- title = MSG( 'base_error.home.title' ); OI.page_title( title ); -%] [%- PROCESS error_message; PROCESS status_message; -%] <h2>[% title %]</h2> <p>[% MSG( 'base_error.home.summary', num_errors, num_days ) %]</p> <div align="center"> [% INCLUDE base_error::list %] [% INCLUDE form_begin( ACTION = 'error_browser', TASK = 'home', method = 'GET' ) %] <table border="0"> <tr [% PROCESS row_color %]> <td>[% MSG( 'base_error.home.num_days_back' ) %]</td> <td>[% INCLUDE form_text( name = 'num_days' value = num_days, size = 3 ) %]</td> <td>[% MSG( 'base_error.home.num_errors' ) %]</td> <td>[% INCLUDE form_text( name = 'num_errors' value = num_errors, size = 3 ) %]</td> <td>[% INCLUDE form_submit( value_key = 'global.button.go' ) %]</td> </tr> </table> [% INCLUDE form_hidden( name = 'num_months', value = num_months ) %] [% INCLUDE form_end %] </div> <hr noshade="noshade" width="25%" /> <div align="center"> <p>[% MSG( 'base_error.home.by_month' ) %]</p> <table border="0"> [% FOREACH month = by_month_sorted -%] [% by_month_url = OI.make_url( ACTION = 'error_browser', TASK = 'by_month', date_spec = month ) -%] <tr align="right"> <td><a href="[% by_month_url %]">[% month %]</a>:</td> <td>[% by_month.$month %]</td> </tr> [% END -%] </table> [% INCLUDE form_begin( ACTION = 'error_browser', TASK = 'home', method = 'GET' ) %] <table border="0"> <tr [% PROCESS row_color %]> <td>[% MSG( 'base_error.home.num_months' ) %]</td> <td>[% INCLUDE form_text( name = 'num_months', value = num_months, size = 3 ) %]</td> <td>[% INCLUDE form_submit( value_key = 'global.button.go' ) %]</td> </tr> </table> [% INCLUDE form_hidden( name = 'num_days', value = num_days ); INCLUDE form_hidden( name = 'num_errors', value = num_errors ) %] [% INCLUDE form_end %] </div> --- NEW FILE: list.tmpl --- [% IF error_list.size > 0 -%] [% INCLUDE table_bordered_begin -%] [% INCLUDE header_row( label_keys = [ 'base_error.time', 'base_error.category', 'base_error.message', ] ) -%] [%- count = 0 -%] [% FOREACH item = error_list -%] [%- show_date_id = item.id | uri; view_url = OI.make_url( ACTION = 'error_browser', TASK = 'display', date_id = show_date_id ) -%] <tr [% PROCESS row_color %]> <td><a href="[% view_url %]">[% OI.date_format( item.time ) %]</a></td> <td>[% item.category %]</td> <td>[% item.message %] </td> </tr> [%- count = count + 1 -%] [% END %] [% INCLUDE table_bordered_end -%] [% ELSE -%] <p>[% MSG( 'base_error.no_errors' ) %]</p> [% END -%] --- NEW FILE: monthly_count.tmpl --- [%- title = MSG( 'base_error.monthly.title', year, month ); OI.page_title( title ); -%] <h2>[% title %]</h2> <p>[% MSG( 'base_error.monthly.by_day', year, month ) %]</p> <ul> [% FOREACH day = days_sorted -%] [% IF breakdown.$day -%] [% by_day_url = OI.make_url( ACTION = 'error_browser', TASK = 'by_day', date_spec = "$year-$month-$day" ) -%] <li><a href="[% by_day_url %]">[% day %]</a>: [% breakdown.$day %]</li> [% END -%] [% END -%] </ul> |
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_error/template In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19648/template Removed Files: error_search_results.tmpl error_search_form.tmpl error_list.tmpl error_filter.tmpl error_detail.tmpl Log Message: OIN-35: remove all old templates --- error_search_results.tmpl DELETED --- --- error_search_form.tmpl DELETED --- --- error_list.tmpl DELETED --- --- error_filter.tmpl DELETED --- --- error_detail.tmpl DELETED --- |
From: Chris W. <la...@us...> - 2005-02-25 05:17:01
|
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_error/msg In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19572/msg Added Files: base_error_messages-en.msg Log Message: add localized messages --- NEW FILE: base_error_messages-en.msg --- base_error.home.title = Recent Errors base_error.home.summary = Most recent [_1] from the last [_2] days. base_error.home.by_month = Errors by month: base_error.home.num_days_back = Days back: base_error.home.num_errors = Errors: base_error.home.num_months = Months back: base_error.time = Error Time base_error.category = Category base_error.message = Message base_error.location = Location base_error.host = Host base_error.user = User base_error.session = Session ID base_error.url = URL Requested base_error.browser = User Agent base_error.referer = Referring URL base_error.detail.title = Error Detail base_error.monthly.title = Error Counts for [_1]/[_2] base_error.monthly.by_day = Errors by day for [_1]/[_2]: base_error.daily.title = Errors for [_1]/[_2]/[_3] base_error.daily.summary = There were [_4] errors on [_1]/[_2]/[_3]: base_error.no_errors = No errors found. base_error.removed_files_ok = Removed [quant, _1, error] ok. base_error.display_no_date = No parameter 'date_id' given to display an error. base_error.display_no_error = No error found with given date ID '[_1]'. base_error.by_day.invalid_date = Cannot lookup errors by day - invalid date specification ([_1]). Should be in 'yyyy-mm-dd' format. base_error.by_month.invalid_date = Cannot lookup errors by month - invalid date specification ([_1]). Should be in 'yyyy-mm' format. |
From: Chris W. <la...@us...> - 2005-02-25 05:16:52
|
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_error/struct In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19480/struct Removed Files: sys_error_oracle.sql sys_error_interbase.sql sys_error.sql Log Message: OIN-35: db structures no longer needed --- sys_error_oracle.sql DELETED --- --- sys_error_interbase.sql DELETED --- --- sys_error.sql DELETED --- |
From: Chris W. <la...@us...> - 2005-02-25 05:16:30
|
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_error/conf In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19424/conf Modified Files: action.ini Log Message: OIN-35: change name from 'error' -> 'error_browser'; add new templates Index: action.ini =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/pkg/base_error/conf/action.ini,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** action.ini 27 Jun 2003 06:02:13 -0000 1.5 --- action.ini 25 Feb 2005 05:16:06 -0000 1.6 *************** *** 1,20 **** ! [error] ! class = OpenInteract2::Action::Error ! is_secure = yes ! task_default = search_form ! c_object_type = error_object ! c_search_fields_exact = category ! c_search_fields_like = message ! c_search_form_template = base_error::error_search_form ! c_search_results_template = base_error::error_search_results ! c_display_template = base_error::error_detail ! [error security] ! DEFAULT = READ ! remove = WRITE ! [error_filter] ! url_none = yes ! template = base_error::error_filter ! is_secure = no ! action_type = template_only --- 1,13 ---- ! [error_browser] ! class = OpenInteract2::Action::Error ! is_secure = yes ! task_default = home ! [error_browser template_source] ! home = base_error::home ! display = base_error::detail ! by_month = base_error::monthly_count ! by_day = base_error::daily_list ! [error_browser security] ! DEFAULT = WRITE |
From: Chris W. <la...@us...> - 2005-02-25 05:15:36
|
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_error/OpenInteract2/Action In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19267/OpenInteract2/Action Modified Files: Error.pm Log Message: OIN-35: completely rewrite action to provide browse-by-date capabilities Index: Error.pm =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/pkg/base_error/OpenInteract2/Action/Error.pm,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** Error.pm 18 Feb 2004 05:25:23 -0000 1.10 --- Error.pm 25 Feb 2005 05:15:28 -0000 1.11 *************** *** 4,13 **** use strict; ! use base qw( OpenInteract2::Action::CommonSearch ! OpenInteract2::Action::CommonDisplay ); ! use Log::Log4perl qw( get_logger ); ! use OpenInteract2::Constants qw( :log ); ! use OpenInteract2::Context qw( CTX ); ! use Text::Wrap qw(); $OpenInteract2::Action::Error::VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/); --- 4,12 ---- use strict; ! use base qw( OpenInteract2::Action ); ! use Log::Log4perl qw( get_logger ); ! use OpenInteract2::Constants qw( :log ); ! use OpenInteract2::Context qw( CTX ); ! use OpenInteract2::ErrorStorage; $OpenInteract2::Action::Error::VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/); *************** *** 15,123 **** my ( $log ); ! sub _search_query_customize { ! my ( $self ) = @_; ! my $request = CTX->request; ! ! # First, set the order ! ! my $order = $request->param( 'sort' ) || 'error_time'; ! $order = ( $order eq 'error_time' ) ? 'error_time DESC' : $order; ! $self->param( c_search_results_order => $order ); ! # Next, set the date_from and/or date_to ! my $where = $self->param( 'c_search_query_where' ) || []; ! my $value = $self->param( 'c_search_query_values' ) || []; ! if ( my $from_date = $request->param_date( 'filter_date_from' ) ) { ! push @{ $where }, 'error_time >= ?'; ! push @{ $value }, $from_date->strftime( '%Y-%m-%d' ); ! } ! if ( my $to_date = $request->param_date( 'filter_date_to' ) ) { ! push @{ $where }, 'error_time <= ?'; ! push @{ $value }, $to_date->strftime( '%Y-%m-%d' ); } ! $self->param( c_search_query_where => $where ); ! $self->param( c_search_query_values => $value ); ! return undef; } ! ! sub _search_customize { ! my ( $self, $template_params ) = @_; ! my $request = CTX->request; ! $template_params->{filterby} = { ! sort => $request->param( 'filter_sort' ), ! message => $request->param( 'filter_message' ), ! category => $request->param( 'filter_category' ), ! date_from => $request->param_date( 'filter_date_from' ), ! date_to => $request->param_date( 'filter_date_to' ), ! }; ! return undef; } ! ! ! # Grab the user here since sometimes the user might be 'superuser' ! # who cannot be seen by mere mortals. This throws an error if you ! # do in the template [% error_user = err.user %] and rather than a ! # TRY/CATCH block we'll just do it here. ! ! sub _display_customize { ! my ( $self, $params ) = @_; ! $params->{error_user} = eval { $params->{error}->user }; ! eval { ! my $error_class = CTX->lookup_object( 'error_object' ); ! $params->{category_list} = ! $error_class->db_select({ ! select => [ 'category' ], ! select_modifier => 'DISTINCT', ! from => [ $error_class->table_name ], ! order => 'category', ! return => 'single-list', }); ! }; } ! ! # Implement 'remove()' ourselves so we can delete multiple objects at ! # once ! ! sub remove { my ( $self ) = @_; ! $log ||= get_logger( LOG_APP ); ! my $request = CTX->request; ! my @error_id = $request->param( 'error_id' ); ! my ( @error_results ); ! my $success = 0; ! foreach my $eid ( @error_id ) { ! $log->is_info && ! $log->info( "Removing error: $eid" ); ! my $error = eval { ! CTX->lookup_object( 'error_object' )->fetch( $eid ) ! }; ! if ( $@ or ! $error ) { ! my $msg = ( $@ ) ! ? "Could not retrieve error [$eid] to remove: $@" ! : "Error [$eid] does not exist, not removed."; ! $log->warn( "Failed to fetch error for removal: $msg" ); ! $self->param_add( error_msg => $msg ); ! push @error_results, $msg; ! next; ! } ! eval { $error->remove }; ! if ( $@ ) { ! $log->error( "Failed to delete error [$eid]: $@" ); ! $self->param_add( error_msg => "Failed to remove [$eid]: $@" ); ! } ! else { ! $success++; ! $log->is_info && ! $log->info( "Removed error ok" ); ! } ! } ! $self->param_add( ! status_msg => "$success objects removed successfully" ); ! return $self->execute( task=> 'search_form' ); } ! 1; \ No newline at end of file --- 14,129 ---- my ( $log ); ! sub _get_store { ! return OpenInteract2::ErrorStorage->new(); ! } ! sub home { ! my ( $self ) = @_; ! $log ||= get_logger( LOG_ACTION ); ! $self->param_from_request( 'num_errors', 'num_days', 'num_months' ); ! $log->fatal( "This is a test fatal message" ); ! my $num_errors = $self->param( 'num_errors' ) || 10; ! my $num_days = $self->param( 'num_days' ) || 14; ! my $num_months = $self->param( 'num_months' ) || 2; ! $log->info( "Error browse home with [errors: $num_errors] ", ! "[days: $num_days] [months: $num_months]" ); ! my $store = _get_store(); ! my @errors = $store->get_most_recent( $num_errors, $num_days ); ! $log->info( "Got ", scalar( @errors ), " recent errors" ); ! my %breakdown = $store->get_breakdown_by_month( months => $num_months ); ! return $self->generate_content({ ! error_list => \@errors, ! num_errors => $num_errors, ! num_days => $num_days, ! num_months => $num_months, ! by_month_sorted => [ sort { $b cmp $a } keys %breakdown ], ! by_month => \%breakdown, ! }); ! } ! sub by_month { ! my ( $self ) = @_; ! $log ||= get_logger( LOG_ACTION ); ! my $req = CTX->request; ! my $date_spec = $req->param( 'date_spec' ); ! my ( $year, $month ) = split /\D+/, $date_spec, 2; ! unless ( $month and $year ) { ! $self->add_error_key( 'base_error.monthly.invalid_date', $date_spec ); ! return $self->execute({ task => 'home' }); } ! $log->info( "finding breakdown for $year/$month" ); ! my %breakdown = _get_store()->get_breakdown_by_day( ! month => $month, year => $year ! ); ! $log->info( "Got breakdown with ", scalar( keys %breakdown ), " days" ); ! return $self->generate_content({ ! year => $year, ! month => $month, ! breakdown => \%breakdown, ! days_sorted => [ sort { $b <=> $a } keys %breakdown ], ! }); } ! sub by_day { ! my ( $self ) = @_; ! $log ||= get_logger( LOG_ACTION ); ! my $req = CTX->request; ! my $date_spec = $req->param( 'date_spec' ); ! my ( $year, $month, $day ) = split /\D+/, $date_spec, 3; ! unless ( $month and $year and $day ) { ! $self->add_error_key( 'base_error.daily.invalid_date', $date_spec ); ! return $self->execute({ task => 'home' }); ! } ! my @errors = _get_store()->get_by_date( date => "$year-$month-$day" ); ! return $self->generate_content({ ! error_list => \@errors, ! year => $year, ! month => $month, ! day => $day, ! }); } ! sub display { ! my ( $self ) = @_; ! $log ||= get_logger( LOG_ACTION ); ! my $req = CTX->request; ! my $date_id = $req->param( 'date_id' ); ! unless ( $date_id ) { ! $self->add_error_key( 'base_error.display_no_date' ); ! return $self->execute({ task => 'home' }); ! } ! my ( $error ) = _get_store()->get_by_date( date_id => $date_id ); ! unless ( $error ) { ! $self->add_error_key( 'base_error.display_no_error', $date_id ); ! return $self->execute({ task => 'home' }); ! } ! return $self->generate_content({ an_error => $error }); } ! sub remove_by_month { my ( $self ) = @_; ! $log ||= get_logger( LOG_ACTION ); ! my $req = CTX->request; ! my $year = $req->param( 'year' ); ! my $month = $req->param( 'month' ); ! my $start = DateTime->new( year => $year, month => $month, day => 1 ); ! my $end = DateTime->last_day_of_month( year => $year, month => $month ); ! my @removed = _get_store()->remove_by_date( $start, $end ); ! $self->add_status_key( 'base_error.removed_files_ok', scalar @removed ); ! return $self->execute({ task => 'home' }); ! } ! sub remove_by_day { ! my ( $self ) = @_; ! $log ||= get_logger( LOG_ACTION ); ! my $req = CTX->request; ! my $year = $req->param( 'year' ); ! my $month = $req->param( 'month' ); ! my $day = $req->param( 'day' ); ! my $date = DateTime->new( year => $year, month => $month, day => $day ); ! my @removed = _get_store()->remove_by_date( $date ); ! $self->add_status_key( 'base_error.removed_files_ok', scalar @removed ); ! return $self->execute({ task => 'home' }); } ! 1; |
From: Chris W. <la...@us...> - 2005-02-25 05:15:18
|
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_error/conf In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19080/conf Removed Files: spops_error_object.ini Log Message: OIN-35: no longer needed (not using SPOPS) --- spops_error_object.ini DELETED --- |
From: Chris W. <la...@us...> - 2005-02-25 05:15:00
|
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_error/OpenInteract2/SQLInstall In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19034/OpenInteract2/SQLInstall Modified Files: Error.pm Log Message: OIN-35: remove structure installs and only keep security Index: Error.pm =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/pkg/base_error/OpenInteract2/SQLInstall/Error.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Error.pm 20 Oct 2003 03:05:53 -0000 1.2 --- Error.pm 25 Feb 2005 05:14:35 -0000 1.3 *************** *** 6,24 **** use base qw( OpenInteract2::SQLInstall ); - # NOTE: No data migrated since the only data we contain are errors :-) - - sub get_structure_set { - return 'error_object'; - } - - # We don't care what the $set is since there's only one - - sub get_structure_file { - my ( $class, $set, $type ) = @_; - return 'sys_error_oracle.sql' if ( $type eq 'Oracle' ); - return 'sys_error_interbase.sql' if ( $type eq 'InterBase' ); - return 'sys_error.sql'; - } - sub get_security_file { return 'install_security.dat'; --- 6,9 ---- |
From: Chris W. <la...@us...> - 2005-02-25 05:14:19
|
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_error/OpenInteract2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18972/OpenInteract2 Removed Files: ErrorObject.pm Log Message: OIN-35: no longer needed --- ErrorObject.pm DELETED --- |
From: Chris W. <la...@us...> - 2005-02-25 05:13:31
|
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_error/msg In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18787/msg Log Message: Directory /cvsroot/openinteract/OpenInteract2/pkg/base_error/msg added to the repository |
From: Chris W. <la...@us...> - 2005-02-25 00:12:49
|
Update of /cvsroot/openinteract/OpenInteract2/t In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11055 Modified Files: utils.pl Log Message: update base_user version Index: utils.pl =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/t/utils.pl,v retrieving revision 1.90 retrieving revision 1.91 diff -C2 -d -r1.90 -r1.91 *** utils.pl 22 Feb 2005 16:56:28 -0000 1.90 --- utils.pl 25 Feb 2005 00:12:25 -0000 1.91 *************** *** 53,57 **** base_template => '3.15', base_theme => '2.10', ! base_user => '2.35', comments => '1.19', full_text => '2.58', --- 53,57 ---- base_template => '3.15', base_theme => '2.10', ! base_user => '2.36', comments => '1.19', full_text => '2.58', |
From: Chris W. <la...@us...> - 2005-02-25 00:12:09
|
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_user In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10852/base_user Modified Files: package.conf Changes Log Message: allow base_user to handle 'login_name' in action parameter insetad of using 'user_id' from request (see OI2::ActionResolver::UserDir) Index: package.conf =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/pkg/base_user/package.conf,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** package.conf 5 Dec 2004 08:51:21 -0000 1.36 --- package.conf 25 Feb 2005 00:11:39 -0000 1.37 *************** *** 1,4 **** name base_user ! version 2.35 author Chris Winters (ch...@cw...) url http://www.openinteract.org/ --- 1,4 ---- name base_user ! version 2.36 author Chris Winters (ch...@cw...) url http://www.openinteract.org/ Index: Changes =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/pkg/base_user/Changes,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** Changes 5 Dec 2004 08:51:21 -0000 1.36 --- Changes 25 Feb 2005 00:11:39 -0000 1.37 *************** *** 1,4 **** --- 1,11 ---- Revision history for OpenInteract package base_user. + 2.36 Thu Feb 24 00:31:11 EST 2005 + + Modify user action so that you can also specify a login name + instead of a user ID. So: /user/display/?login_name=chris will + work, as will /~chris/ when OI2::ActionResolver::UserDir is + committed... + 2.35 Sat Dec 4 00:06:24 EST 2004 |
From: Chris W. <la...@us...> - 2005-02-25 00:11:48
|
Update of /cvsroot/openinteract/OpenInteract2/pkg/base_user/OpenInteract2/Action In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10852/base_user/OpenInteract2/Action Modified Files: User.pm Log Message: allow base_user to handle 'login_name' in action parameter insetad of using 'user_id' from request (see OI2::ActionResolver::UserDir) Index: User.pm =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/pkg/base_user/OpenInteract2/Action/User.pm,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** User.pm 5 Dec 2004 08:51:21 -0000 1.19 --- User.pm 25 Feb 2005 00:11:39 -0000 1.20 *************** *** 82,85 **** --- 82,109 ---- + # override to deal with 'login_name' instead of 'user_id' being used... + sub display { + my ( $self ) = @_; + $self->_check_params_for_login_name(); + return $self->SUPER::display(); + } + + sub display_form { + my ( $self ) = @_; + $self->_check_params_for_login_name(); + return $self->SUPER::display_form(); + } + + sub _check_params_for_login_name { + my ( $self ) = @_; + my $user_id = CTX->request->param( 'user_id' ); + if ( ! $user_id and my $login = $self->param( 'login_name' ) ) { + my $user = CTX->lookup_object( 'user' )->fetch_by_login_name( $login ); + if ( $user ) { + $self->param( c_object => $user ); + } + } + } + ######################################## # COMMON CUSTOMIZATIONS |
From: Chris W. <la...@us...> - 2005-02-25 00:07:32
|
Update of /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9799/OpenInteract2 Added Files: Error.pm ErrorStorage.pm Log Message: OIN-35: add simple property + serialization object (::Error) and separate object (::ErrorStorage) to put the in the right place and find collections of them by date --- NEW FILE: Error.pm --- package OpenInteract2::Error; # $Id: Error.pm,v 1.1 2005/02/25 00:07:19 lachoy Exp $ use strict; use base qw( Class::Accessor::Fast ); use DateTime::Format::Strptime; use File::Basename qw( dirname ); use File::Path qw( mkpath ); use OpenInteract2::Context qw( CTX ); use OpenInteract2::Exception qw( oi_error ); use Template; $OpenInteract2::Error::VERSION = sprintf("%d.%02d", q$Revision: 1.1 $ =~ /(\d+)\.(\d+)/); my $DATE_PATTERN = '%Y-%m-%d %H:%M:%S %3N'; my ( $PARSER ); my %FIELDS = map { $_ => 1 } qw( id file_storage message time category class line host user_id username session browser referer url ); __PACKAGE__->mk_accessors( keys %FIELDS ); sub new { my ( $class, %params ) = @_; $class->_initialize_parser; if ( $params{file_storage} ) { return $class->_read_from_file( $params{file_storage} ); } my $self = bless( {}, $class ); for ( keys %FIELDS ) { $self->$_( $params{ $_ } ) if ( $params{ $_ } ); } return $self; } sub _initialize_parser { return if ( $PARSER ); my %params = ( pattern => $DATE_PATTERN ); if ( CTX ) { $params{time_zone} = CTX->timezone_object; } $PARSER = DateTime::Format::Strptime->new( %params ); } sub _read_from_file { my ( $class, $file ) = @_; unless ( -f $file ) { oi_error "Cannot read serialized error from file '$file' -- ", "file does not exist."; } open( IN, '<', $file ) || oi_error "Cannot read serialized error from '$file' -- $!"; my $self = $class->new(); while ( <IN> ) { chomp; if ( /^(\w+)\s+:=\s+(.*)$/ ) { my $prop = lc $1; my $val = $2; next unless ( $prop eq 'user' || $FIELDS{ $prop } ); if ( $prop eq 'time' ) { $self->time( $PARSER->parse_datetime( $val ) ); } elsif ( $prop eq 'user' ) { my ( $name, $id ) = split /\s+\|\s+/, $val, 2; $self->username( $name ); $self->user_id( $id ); } else { $self->$prop( $val ); } } } close( IN ); $self->file_storage( $file ); return $self; } sub save { my ( $self, $file ) = @_; unless ( $file ) { oi_error "Parameter 'file' must be defined to store an error."; } if ( -f $file ) { oi_error "Cannot overwrite existing file '$file' with error contents"; } eval { mkpath( dirname( $file ) ) }; if ( $@ ) { oi_error "Cannot create directories for '$file': $@"; } my $error_template = $self->_error_template(); my $template = Template->new(); $template->process( \$error_template, { e => $self }, $file ) || oi_error "Cannot process error template to '$file': ", $template->error(); $self->file_storage( $file ); return $file; } sub _error_template { return <<ERROR; time := [% e.time.strftime( '$DATE_PATTERN' ) %] message := [% e.message %] url := [% e.url %] category := [% e.category %] class := [% e.class %] line := [% e.line %] user := [% e.username %] | [% e.user_id %] session := [% e.session %] host := [% e.host %] browser := [% e.browser %] referer := [% e.referer %] ERROR } 1; __END__ =head1 NAME OpenInteract2::Error - Simple property object that knows how to un/serialize from/to a file =head1 SYNOPSIS # create a new error message my $error = OpenInteract2::Error->new( message => "An error happened!", class => 'OpenInteract2::Foo', line => 444, ); # pass to storage class to save to automatic location my $storage = OpenInteract2::ErrorStorage->new(); $storage->save( $error ); # specify location to store error $error->save( '/path/to/error-foo.txt' ); =head1 DESCRIPTION This is a simple property object that can store itself to a file and populate itself from a file. Generally you won't work with this directly. It will get created automatically when you log an error message or higher with log4perl. For instance: package My::Class; use Log::Log4perl qw( get_logger ); my $log = get_logger(); sub do_foo { my ( $self ) = @_; unless ( $self->check_foo ) { $log->error( "Check for 'foo' failed -- cannot do the do" ); } } This will trigger our custom log4perl appender (L<OpenInteract2::Log::OIAppender>) which will create a new error object, populate it with information from the logger and current request, then send it to L<OpenInteract2::ErrorStorage>. The storage class takes care of organizing the errors in the filesystem and passes a valid file for the error object to use in its C<save()> method. =head1 CLASS METHODS B<new( %params )> Creates a new object seeded with data from C<%params>. We only set data for which we have known properties -- see below. If you pass in a valid file for parameter 'file_storage' we retrieve the error's information from the file specified there and populate a new object with it. =head1 OBJECT METHODS B<save( $file )> Stores the error object in C<$file>. Throws an exception if C<$file> already exists or if we cannot write to it. This method will create all necessary directories to store C<$file> properly. Returns: C<$file> if object stored properly. =head2 Properties B<time> DateTime object representing when error was raised. B<message> Error message B<category> Typically one of the log4perl categories like 'OI2.ACTION'. Can be set to an arbitrary value though. B<class> Class where the error was raised. B<line> Line number in which the error was raised. =head2 Properties: Request-specific These properties are generally populated only when there's an active request. B<url> URL requested. B<host> IP address or hostname of requester. B<user_id> ID of user making the request. B<username> Name of user making the request. B<session> Session ID associated with request. B<browser> User-agent string. B<referer> String from referer header =head1 SEE ALSO L<OpenInteract2::ErrorStorage> L<OpenInteract2::Log::OIAppender> =head1 COPYRIGHT Copyright (c) 2005 Chris Winters. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHORS Chris Winters E<lt>ch...@cw...E<gt> --- NEW FILE: ErrorStorage.pm --- package OpenInteract2::ErrorStorage; # $Id: ErrorStorage.pm,v 1.1 2005/02/25 00:07:19 lachoy Exp $ use strict; use base qw( Exporter ); use DateTime; use DateTime::Format::Strptime; use File::Spec::Functions qw( catdir catfile ); use Log::Log4perl qw( get_logger ); use OpenInteract2::Context qw( CTX ); use OpenInteract2::Exception qw( oi_error ); use OpenInteract2::Error; use Scalar::Util qw( blessed ); $OpenInteract2::ErrorStorage::VERSION = sprintf("%d.%02d", q$Revision: 1.1 $ =~ /(\d+)\.(\d+)/); @OpenInteract2::ErrorStorage::EXPORT_OK = qw( DEFAULT_RECENT_ERRORS DEFAULT_RECENT_MONTHS DEFAULT_RECENT_DAYS DAY_DATE_PATTERN FILE_DATE_PATTERN ID_DATE_PATTERN ); use constant DEFAULT_RECENT_ERRORS => 5; use constant DEFAULT_RECENT_MONTHS => 6; use constant DEFAULT_RECENT_DAYS => 30; use constant DAY_DATE_PATTERN => '%Y-%m-%d'; use constant FILE_DATE_PATTERN => '%H%M%S-%3N'; use constant ID_DATE_PATTERN => '%Y%m%d-%H%M%S-%3N'; # NOTE: unlike the rest of OI2 we use a class-based logger here so # that OI2::Log::OIAppender doesn't try and send messages sent BY this # class TO this class. my $log = get_logger( __PACKAGE__ ); my ( $PARSER ); sub new { my ( $class, $error_dir ) = @_; if ( ! $error_dir and CTX ) { $error_dir ||= CTX->lookup_directory( 'error' ); } else { $log->warn( "A context is not available and you did not pass in ", "a directory to which I can save errors. Any errors ", "stored with this object will be discarded" ); } $class->_initialize_parser; return bless( { error_dir => $error_dir }, $class ); } sub _initialize_parser { my ( $class ) = @_; return if ( $PARSER ); my %params = ( pattern => DAY_DATE_PATTERN ); if ( CTX ) { $params{time_zone} = CTX->timezone_object; } $PARSER = DateTime::Format::Strptime->new( %params ); } sub _now { return ( CTX ) ? CTX->create_date() : DateTime->now(); } sub save { my ( $self, $error_data ) = @_; unless ( $self->{error_dir} ) { $log->warn( "Will not store error -- no error directory set" ); return; } my ( $error ); if ( blessed( $error_data ) ) { $error = $error_data; } else { $error_data ||= {}; $error_data->{time} ||= _now(); $error = OpenInteract2::Error->new( %{ $error_data } ); } return $error->save( $self->_filename_from_date( $error_data->{time} ) ); } sub get_most_recent { my ( $self, $num_errors, $max_days ) = @_; $num_errors ||= DEFAULT_RECENT_ERRORS; $max_days ||= DEFAULT_RECENT_DAYS; my $current_days_back = 0; my $start = _now(); my @errors = (); while ( scalar @errors < $num_errors and $current_days_back < $max_days ) { my $find_dt = $start->clone()->subtract( days => $current_days_back ); push @errors, $self->_read_by_date( $find_dt ); $current_days_back++; } if ( scalar @errors > $num_errors ) { splice( @errors, ( scalar @errors - $num_errors ) ); } return $self->_add_id( @errors ); } sub get_by_date { my ( $self, %date_info ) = @_; my @errors = (); my $date_id = $date_info{date_id}; if ( $date_id ) { my $fmt = DateTime::Format::Strptime->new( pattern => ID_DATE_PATTERN, ); if ( my $dt = $fmt->parse_datetime( $date_id ) ) { my $file = $self->_filename_from_date( $dt ); my $error = eval { OpenInteract2::Error->new( file_storage => $file ) }; push @errors, $error if ( $error ); } } else { my $date = $date_info{date} || _now()->strftime( DAY_DATE_PATTERN ); my $span = $date_info{days} || 1; my @all_dates = $self->_generate_range( 'days', $date, $span - 1 ); foreach my $dt ( @all_dates ) { push @errors, $self->_read_by_date( $dt ); } } return $self->_add_id( @errors ); } sub _add_id { my ( $self, @errors ) = @_; for ( @errors ) { $_->id( $_->time->strftime( ID_DATE_PATTERN ) ); } return @errors; } sub _read_by_date { my ( $self, $dt ) = @_; my @errors = (); foreach my $file ( $self->_files_by_date( $dt ) ) { my $error = OpenInteract2::Error->new( file_storage => $file ); if ( $error ) { push @errors, $error; } } return $self->_add_id( @errors ); } sub get_breakdown_by_month { my ( $self, %date_info ) = @_; my $now = _now(); my $year = $date_info{year} || $now->year(); my $month = $date_info{month} || $now->month(); my $span = $date_info{months} || DEFAULT_RECENT_MONTHS; my $end = DateTime->new( year => $year, month => $month, day => $now->day ); my $start = $end->clone()->subtract( months => $span, days => 7 ); my @all_months = $self->_generate_range( 'months', $start, $end ); my %bd = (); foreach my $dt ( @all_months ) { my $month_spec = $dt->strftime( '%Y-%m' ); $bd{ $month_spec } = $self->count_errors( $month_spec ); } return %bd; } sub get_breakdown_by_day { my ( $self, %date_info ) = @_; my $now = _now(); my $year = $date_info{year} || $now->year(); my $month = $date_info{month} || $now->month(); my $start = DateTime->new( year => $year, month => $month, day => 1 ); my $end = DateTime->last_day_of_month( year => $year, month => $month ); my @all_days = $self->_generate_range( 'days', $start, $end ); my %bd = (); foreach my $dt ( @all_days ) { next if ( $dt > $now ); $bd{ $dt->strftime( '%d' ) } = $self->count_errors( $dt ); } return %bd; } sub count_errors { my ( $self, $date_spec ) = @_; if ( blessed( $date_spec ) ) { return $self->_count_errors_in_day( $date_spec ); } my ( $year, $month, $day ) = split /\D/, $date_spec; my $count = 0; my @days = (); if ( $day ) { push @days, $day } else { push @days, $self->_get_error_days_in_month( "$year-$month" ); } foreach my $day ( @days ) { my $dt = $PARSER->parse_datetime( "$year-$month-$day" ); $count += $self->_count_errors_in_day( $dt ); } return $count; } sub _get_error_days_in_month { my ( $self, $month_spec ) = @_; my $month_dir = catdir( $self->{error_dir}, $month_spec ); return () unless ( -d $month_dir ); opendir( MON, $month_dir ) || oi_error "Cannot open '$month_dir' for reading: $!"; my @days = grep /^\d+/, grep { -d $_ } readdir( MON ); closedir( MON ); return @days; } sub _count_errors_in_day { my ( $self, $dt ) = @_; my $day_dir = $self->_dirname_from_date( $dt ); return 0 unless ( -d $day_dir ); opendir( ERR, $day_dir ) || oi_error "Cannot open '$day_dir' for reading: $!"; my @errors = grep /\.txt$/, grep { -f $_ } readdir( ERR ); closedir( ERR ); return scalar @errors; } sub remove_by_date { my ( $self, $date, $span ) = @_; $span ||= 1; my @all_dates = $self->_generate_range( 'days', $date, $span ); my @removed = (); foreach my $dt ( @all_dates ) { foreach my $file ( $self->_files_by_date( $dt ) ) { if ( $self->_remove_file( $file ) ) { push @removed, $file; } } } return @removed; } sub _files_by_date { my ( $self, $dt ) = @_; my $date_dir = $self->_dirname_from_date( $dt ); my @files = ( -d $date_dir ) ? <$date_dir/*> : (); return sort { $b cmp $a } @files; } sub _filename_from_date { my ( $self, $dt ) = @_; return catfile( $self->_dirname_from_date( $dt ), $dt->strftime( '%H%M%S-%3N.txt' ) ); } sub _dirname_from_date { my ( $self, $dt ) = @_; return catdir( $self->{error_dir}, $dt->strftime( '%Y-%m' ), $dt->strftime( '%d' ) ); } sub _generate_range { my ( $self, $type, $date, $end_range ) = @_; my @dates = (); my $start = $self->_parse_date( $date ); push @dates, $start; my ( $span ); if ( blessed( $end_range ) ) { # treat as DateTime my $duration = $end_range - $start; $span = $duration->$type(); # e.g., $duration->days(); warn "Duration between '", $end_range->strftime( '%F %T' ), "' and", "'", $start->strftime( '%F %T' ), "' is $span $type"; } else { $span = $end_range; } if ( $span > 0 ) { for ( 1 .. $span ) { push @dates, $start->clone()->add( $type => $_ ); } } return @dates; } sub _parse_date { my ( $self, $date ) = @_; return $date if ( blessed( $date ) ); my $dt = $PARSER->parse_datetime( $date ); unless ( $dt ) { oi_error "Dates for error storage must be in format ", "'", DAY_DATE_PATTERN, "'. (Date given: $date)"; } return $dt; } sub _remove_file { my ( $self, $file ) = @_; return unless ( -f $file ); unless ( unlink( $file ) ) { $log->warn( "Failed to remove file '$file': $!" ); return; } return $file; } 1; __END__ =head1 NAME OpenInteract2::ErrorStorage - Serialize serious errors to the filesystem =head1 SYNOPSIS # Default usage - get path from available context my $storage = OpenInteract2::ErrorStorage->new(); # ...you can also specify the error directory my $storage = OpenInteract2::ErrorStorage->new( '/path/to/errors' ); # Store an error my $file = $storage->save( \%error_info ); _ # Get error distribution by day for the current month... my %breakdown = $storage->get_breakdown_by_day(); # ...for a specific month in the same year my %breakdown = $storage->get_breakdown_by_day( month => 2 ); # ...for a specific month my %breakdown = $storage->get_breakdown_by_day( month => 2, year => 2005 ); # Get error distributions by month over a span of 6 months # from the current month: my %breakdown = $storage->get_breakdown_by_month(); # Get error distributions by month over a span of 3 months from a # specific month (will give you 1-2005, 2-2005, 3-2005) my %breakdown = $storage->get_breakdown_by_month( year => 2005, month => 1, months => 3 ); # Get most recent 5 errors from the last 30 days (defaults) my @errors = $storage->get_most_recent(); # Get most recent 10 errors from the last 30 days my @errors = $storage->get_most_recent( 10 ); # Get most recent 10 errors but only in the last 2 days my @errors = $storage->get_most_recent( 10, 2 ); # Get all errors from today my @errors = $storage->get_by_date(); # ...from yesterday and today my @errors = $storage->get_by_date( days => 2 ); # ...from a particular day my @errors = $storage->get_by_date( date => '2005-04-01' ); # ...from a particular day and the following 6 days my @errors = $storage->get_by_date( date => '2005-04-01', days => 7 ); # Each member is an OpenInteract2::Error object... foreach my $error ( @errors ) { print "Error time: ", $error->time->strftime( '%Y-%m-%d %H:%M' ); ... } # Remove errors for a particular day my @deleted_files = $storage->remove_by_date( '2005-02-28' ); # Same thing... my @deleted_files = $storage->remove_by_date( '2005-02-28', 1 ); # Remove errors for a date range -- in this case, for 2005-02-28 and # the following six days my @deleted_files = $storage->remove_by_date( '2005-02-28', 7 ); =head1 DESCRIPTION This class is responsible for storing, retrieving and removing errors from the filesystem. These errors are typically generated by calls to L<Log::Log4perl> at an C<ERROR> level or higher, but the actual level is configurable in your logging configuration. The data stored on disk are very simple and human-readable. The C<base_error> package also contains actions for browsing the errors and clearing out old errors. The directory structure for storing errors is hashed by date. So instead of everything in one directory you'll have: error_dir/2005-05/01/*.txt error_dir/2005-05/02/*.txt error_dir/2005-06/01/*.txt error_dir/2005-06/02/*.txt The files stored in each day's directory are timestamped (easy to order). So you might have: error_dir/2005-05/01/041532-451.txt # 4:15 AM, 32 seconds, 451 milliseconds error_dir/2005-05/01/212001-991.txt # 9:12 PM, 1 second, 991 milliseconds ... The data stored in each file is in a human-readable but easily parseable format (no XML, INI or Perl). =head1 CLASS METHODS B<new( [ $error_dir ] )> Create a new storage object. If C<$error_dir> not specified we pull the information from the available L<OpenInteract2::Context> object. =head1 OBJECT METHODS NOTE: Wherever C<$date> is specified we take it in the format '%Y-%m-%d', or '2005-05-01' for May 1, 2005. If you give us a date in the wrong format we throw an exception. NOTE: All errors returned from this method have their C<id> attribute set to a unique identifier derived from the date. It matches the pattern: %Y-%m %d %H%M%S-%3N You'll notice that this conveniently matches the pattern we use to store the errors: %Y-%m/%d/%H%M%S-%3N.txt B<save( \%error_info )> Create a L<OpenInteract2::Error> object with C<\%error_info> and store it to disk. Keys in C<\%error_info> match up with the properties in L<OpenInteract2::Error>. Returns: filename where object stored. B<get_most_recent( [ $num_errors ], [ $max_days ] )> Retrieve most recent errors. With no arguments it returns the most recent 5 errors from the last 30 days. Parameters are: =over 4 =item B<num_errors> (int; optional -- defaults to 5) Number of errors to retrieve. =item B<max_days> (int; optional -- defaults to 30) Maximum number of days to look back to satisfy C<num_errors>. =back Example: # Get most recent 20 errors from the last 30 days my @errors = $storage->get_most_recent( 20 ); # Get most recent 20 errors, but only from the last week; if 20 # errors not stored in the last week @errors will be smaller than 20 my @errors = $storage->get_most_recent( 20, 7 ); B<get_by_date( [ %date_info ] )> Retrieve list of errors by date. With no arguments it returns all errors from today. Parameters are: =over 4 =item B<date> (yyyy-mm-dd; optional -- defaults to today) Date, or with C<days> the starting date, for which I should retrieve errors. =item B<days> (int; optional -- defaults to 1) Number of days, inclusive, starting with C<date>, for which I should retrieve errors. =item B<date_id> (yyyy-mm dd HHMMSS-NNN; optional) Pattern by which we can retrieve a particular date. The return list will have only one element if the error with this date is found, zero if no.t =back Example: # Get all errors from May 1, 2005 my @errors = $storage->get_by_date( '2005-05-01' ); # Get all errors from May 1, 2, and 3 in 2005 my @errors = $storage->get_by_date( '2005-05-01', 3 ); B<get_breakdown_by_month( %date_info )> Returns a hash of errors in storage indexed by month. The keys of the hash are formatted 'yyyy-mm', or '2005-02' for 'February, 2005' and the value for each key is a count of errors in that month. Parameters: =over 4 =item B<year> (optional; defaults to current year) =item B<month> (optional; defaults to current month) =item B<months> (optional; defaults to 6) Number of months for which you want a breakdown -- it's an implied negative number since the year/month specify the latest date for which you want a report. =back Example: # Current month - 6 my %bd = $storage->get_breakdown_by_month(); # Jan 2005, Dec 2004, Nov 2004 my %bd = $storage->get_breakdown_by_month( year => 2005, month => 1, months => 3 ); B<get_breakdown_by_day( %date_info )> Returns a hash of errors in storage in a particular month indexed by day. The keys of the hash are formatted 'dd', or '09' for the ninth day of the month. Each key is a count of errors for that day. Parameters: =over 4 =item B<year> (optional; defaults to current year) =item B<month> (optional; defaults to current month) =back Example: # Get error counts for days in the current month: my %bd = $self->get_breakdown_by_day(); # Get error counts for days in Feb 2005: my %bd = $self->get_breakdown_by_day( year => 2005, month => 2 ); B<remove_by_date( $date, [ $days ] )> Removes multiple error files by date. Returns a list of files deleted. Parameters are: =over 4 =item B<date> (yyyy-mm-dd; required) Date, or with C<days> the starting date, for which I should remove the files. =item B<days> (int; optional -- defaults to 1) Number of days, inclusive, starting with C<date>, for which I should remove the files. =back Example: # Remove all errors from May 1, 2005 $storage->remove_by_date( '2005-05-01' ); # Remove all errors from May 1, 2, and 3 in 2005 $storage->remove_by_date( '2005-05-01', 3 ); =head1 SEE ALSO L<OpenInteract2::Error> L<OpenInteract2::Log::OIAppender> =head1 COPYRIGHT Copyright (c) 2005 Chris Winters. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHORS Chris Winters E<lt>ch...@cw...E<gt> |