#-*- perl -*- # # Copyright (C) 2001,2002 Ken'ichi Fukamachi # All rights reserved. This program is free software; you can # redistribute it and/or modify it under the same terms as Perl itself. # # $FML: Print.pm,v 1.20 2001/12/22 09:21:20 fukachan Exp $ # package Mail::ThreadTrack::Print; use strict; use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD); use Carp; use Mail::ThreadTrack::Print::Utils qw(decode_mime_string STR2EUC); =head1 NAME Mail::ThreadTrack::Print - dispatcher to print out thread =head1 SYNOPSIS =head1 DESCRIPTION =head1 METHODS =head2 list() show todo list without article summary. =cut # Descriptions: show todo list without article summary. # Arguments: OBJ($self) # Side Effects: none # Return Value: none sub list { my ($self, @opts) = @_; $self->_load_library(); $self->db_open(); $self->_do_list(@opts); $self->db_close(); } =head2 summary() show the thread summary, which is todo list C article summary. Each row that C returns has a set of C, C, C, C and C, which is a list of articles with the thread-id. summary show entries by the thread_id order. For example, date age status thread id articles ------------------------------------------------------------ 2001/02/07 3.6 going elena_#00000450 807 808 809 2001/02/07 3.1 open elena_#00000451 810 2001/02/07 3.0 open elena_#00000452 812 2001/02/07 3.0 open elena_#00000453 813 2001/02/07 3.0 going elena_#00000454 814 815 2001/02/10 0.1 open elena_#00000456 821 =cut # Descriptions: show todo list with article summary. # Arguments: OBJ($self) # Side Effects: none # Return Value: none sub summary { my ($self, @opts) = @_; $self->_load_library(); $self->db_open(); $self->_do_summary(@opts); $self->db_close(); } =head2 review() show a chain of article summary in each thread. This summary is a collection of short summary of articles in one thread. =cut # Descriptions: show summary for each thread # Arguments: OBJ($self) VARARGS # Side Effects: none # Return Value: none sub review { my ($self, @opts) = @_; $self->_load_library(); $self->db_open(); $self->_do_review(@opts); $self->db_close(); } # Descriptions: load subclasses, change @INC # Arguments: OBJ($self) # Side Effects: @INC modified # Return Value: none sub _load_library { my ($self) = @_; my $mode = $self->get_mode || 'text'; require Mail::ThreadTrack::Print::Message; require Mail::ThreadTrack::Print::Sort; my @list = qw(Mail::ThreadTrack::Print::Message Mail::ThreadTrack::Print::Sort); if ($mode eq 'text') { require Mail::ThreadTrack::Print::Text; push(@list, 'Mail::ThreadTrack::Print::Text'); } elsif ($mode eq 'html') { require Mail::ThreadTrack::Print::HTML; push(@list, 'Mail::ThreadTrack::Print::HTML'); } unshift(@ISA, @list); } # # SUMMARY MODE # # Descriptions: dispatcher to show todo list with article summary. # Arguments: OBJ($self) # Side Effects: none # Return Value: none sub _do_summary { my ($self) = @_; $self->__do_summary( { mode => 'summary' }); } # Descriptions: dispatcher to show todo list without article summary. # Arguments: OBJ($self) # Side Effects: none # Return Value: none sub _do_list { my ($self) = @_; $self->__do_summary( { mode => 'list' }); } # Descriptions: get thread id list with status != 'close' and # show summary for the list # Arguments: OBJ($self) HASH_REF($option) # Side Effects: none # Return Value: none sub __do_summary { my ($thread, $option) = @_; my $mode = $thread->get_mode || 'text'; my $config = $thread->{ _config }; # rh: thread id list picked from status.db my $thread_id_list = $thread->list_up_thread_id(); # 1. sort the thread output order by cost # 2. print the thread brief summary in that order. # 3. show short summary for each message if needed (mode dependent) if (@$thread_id_list) { $thread->sort_thread_id($thread_id_list); # reverse order (first thread is the latest one) if reverse mode if ($config->{ reverse_order }) { @$thread_id_list = reverse @$thread_id_list; } $thread->_print_thread_summary($thread_id_list); if ($option->{ mode } eq 'summary') { $thread->_print_message_summary($thread_id_list); } } } # Descriptions: show thread summary # Arguments: OBJ($self) ARRAY_REF($thread_id_list) # Side Effects: none # Return Value: none sub _print_thread_summary { my ($self, $thread_id_list) = @_; my $mode = $self->get_mode || 'text'; my $db = $self->{ _hash_table }; # guide of presentation $self->__start_thread_summary(); # XXX dynamic binding # show brief summary along thread_id list my ($thread_id, @article_id, $article_id, $date, $age, $status) = (); my $date_h = new Mail::Message::Date; for $thread_id (@$thread_id_list) { next unless defined $db->{ _articles }->{ $thread_id }; # get the first $article_id from the article_id list (@article_id) = split(/\s+/, $db->{ _articles }->{ $thread_id }); $article_id = $article_id[0]; # format $date for the $article_id $date = $date_h->YYYYxMMxDD( $db->{ _date }->{ $article_id } , '/'); $age = $self->{ _age }->{ $thread_id }; $status = $db->{ _status }->{ $thread_id }; $self->__print_thread_summary( { date => $date, age => $age, status => $status, thread_id => $thread_id, articles => $db->{ _articles }->{ $thread_id }, }); # XXX dynamic binding } $self->__end_thread_summary(); # XXX dynamic binding } # Descriptions: show the first few lines of the first message in the thread # Arguments: OBJ($self) STR($thread_id) # Side Effects: none # Return Value: none sub _print_message_summary { my ($self, $thread_id) = @_; $self->__print_message_summary($thread_id); } # # REVIEW MODE # # Descriptions: show brief summary chain of messages in the thread # Arguments: OBJ($self) STR($str) NUM($min) NUM($max) # Side Effects: none # Return Value: none sub _do_review { my ($self, $str, $min, $max) = @_; my $config = $self->{ _config }; my $spool_dir = $config->{ spool_dir }; my $fd = $self->{ _fd } || \*STDOUT; my $db = $self->{ _hash_table }; my %uniq = (); my $is_first = 0; # translate the given parameter (MH style) # get HASH ARRAY of specified range use Mail::Message::MH; my $range = Mail::Message::MH->expand($str, $min, $max); # reverse order (first thread is the latest one) if reverse mode if ($config->{ reverse_order }) { @$range = reverse @$range;} ID_LIST: for my $id (@$range) { next ID_LIST unless defined $id; if ($id =~ /^\d+$/) { # create thread identifier string: e.g. 100 -> elena/100 my $tid = $self->_create_thread_id_strings($id); # check thread id $tid exists really ? if (defined $db->{ _articles }->{ $tid }) { printf $fd "\n>Thread-Id: %-10s %s\n", $tid; # different treatment for the fisrt article in this thread $is_first = 1; # show all articles in this thread ARTICLE: for my $aid (split(/\s+/, $db->{ _articles }->{ $tid })) { # ensure uniquness next ARTICLE if $uniq{ $aid }; $uniq{ $aid } = 1; # show header only for the first message in this thread if ($is_first) { undef $self->{ _no_header_summary }; $is_first = 0; } else { $self->{ _no_header_summary } = 1; } my $file = File::Spec->catfile($spool_dir, $aid); if (-f $file) { $self->print( $self->message_summary($file) ); print $fd "\n"; } } } } } } =head2 show($tid) show all articles in specified thread. =cut # Descriptions: show all articles in specified thread. # Arguments: OBJ($self) STR($tid) # Side Effects: none # Return Value: none sub show { my ($self, $tid) = @_; $self->_load_library(); $self->db_open(); $self->show_articles_in_thread($tid); $self->db_close(); } =head2 print(str) print str with special effect e.g. quoting if needed. The function depends the mode, 'text' or 'html'. =cut # Descriptions: wrapper of print() # Arguments: OBJ($self) STR($str) # Side Effects: quote if needed # Return Value: none sub print { my ($self, $str) = @_; my $mode = $self->get_mode || 'text'; my $fd = $self->{ _fd } || \*STDOUT; if ($mode eq 'text') { print $fd $str; } elsif ($mode eq 'html') { $str = &_quote($str); $str =~ s/\n/
\n/g; print $fd $str; } } # Descriptions: quote for html metachars # Arguments: STR($str) # Side Effects: none # Return Value: STR sub _quote { my ($str) = @_; $str =~ s/&/&/g; $str =~ s//>/g; $str =~ s/\"/"/g; return $str; } =head1 CODING STYLE See C on fml coding style guide. =head1 AUTHOR Ken'ichi Fukamachi =head1 COPYRIGHT Copyright (C) 2001,2002 Ken'ichi Fukamachi All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 HISTORY Mail::ThreadTrack::Print appeared in fml5 mailing list driver package. See C for more details. =cut 1;