summaryrefslogtreecommitdiff
path: root/fml/lib/Mail/ThreadTrack
diff options
context:
space:
mode:
authorfukachan <fukachan>2004-03-31 12:53:50 +0000
committerfukachan <fukachan>2004-03-31 12:53:50 +0000
commit5432a7011fcb4386b56fc044a54ec4c4dd2da0e5 (patch)
tree0d73b11db0e7a903d7b020323b97f6aaaa8cd10d /fml/lib/Mail/ThreadTrack
parent408f950159c3aae27154eaaceb15d6d91095d9d9 (diff)
downloadfml8-5432a7011fcb4386b56fc044a54ec4c4dd2da0e5.tar.gz
fml8-5432a7011fcb4386b56fc044a54ec4c4dd2da0e5.tar.bz2
fml8-5432a7011fcb4386b56fc044a54ec4c4dd2da0e5.zip
Mail::ThreadTrack is obsoleted. remove related codes.
Diffstat (limited to 'fml/lib/Mail/ThreadTrack')
-rw-r--r--fml/lib/Mail/ThreadTrack/Analyze.pm663
-rw-r--r--fml/lib/Mail/ThreadTrack/DB.pm321
-rw-r--r--fml/lib/Mail/ThreadTrack/HeaderRewrite.pm133
-rw-r--r--fml/lib/Mail/ThreadTrack/Print.pm419
-rw-r--r--fml/lib/Mail/ThreadTrack/Print/HTML.pm291
-rw-r--r--fml/lib/Mail/ThreadTrack/Print/Message.pm253
-rw-r--r--fml/lib/Mail/ThreadTrack/Print/Sort.pm124
-rw-r--r--fml/lib/Mail/ThreadTrack/Print/Text.pm247
-rw-r--r--fml/lib/Mail/ThreadTrack/Print/Utils.pm115
9 files changed, 0 insertions, 2566 deletions
diff --git a/fml/lib/Mail/ThreadTrack/Analyze.pm b/fml/lib/Mail/ThreadTrack/Analyze.pm
deleted file mode 100644
index 96b01a6b..00000000
--- a/fml/lib/Mail/ThreadTrack/Analyze.pm
+++ /dev/null
@@ -1,663 +0,0 @@
-#-*- perl -*-
-#
-# Copyright (C) 2001,2002,2003 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: Analyze.pm,v 1.32 2003/07/21 11:29:15 fukachan Exp $
-#
-
-package Mail::ThreadTrack::Analyze;
-use strict;
-use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD);
-use Carp;
-
-# XXX-TODO: we should remove not used function ?
-
-my $debug = 0;
-
-=head1 NAME
-
-Mail::ThreadTrack::Analyze - analyze mail thread relation
-
-=head1 SYNOPSIS
-
-See C<Mail::ThreadTrack> perl module for more detail.
-
-=head1 DESCRIPTION
-
-=head1 METHODS
-
-=head2 analyze($mesg)
-
-C<$mesg> is Mail::Message object.
-
-This is top level entrance for
-
-1) assign a new thread or extract the existing thread-id from the subject.
-
-2) update thread status if needed.
-
-3) update database.
-
-=cut
-
-
-# Descriptions: top level entrance
-# Arguments: OBJ($self) OBJ($msg)
-# $msg = "Mail::Messge object"
-# Side Effects: none
-# Return Value: none
-sub analyze
-{
- my ($self, $msg) = @_;
-
- $self->assign($msg);
- $self->rewrite_header($msg) if $self->{ _is_rewrite_header };
- $self->update_thread_status($msg);
- $self->update_db($msg);
-}
-
-
-=head2 assign($msg)
-
-analyze message given by $msg and assign thread id if needed.
-
-=cut
-
-
-# Descriptions: given string looks like subject or not
-# Arguments: STR($subject)
-# Side Effects: none
-# Return Value: 1 or 0
-sub _is_reply
-{
- my ($subject) = @_;
-
- use Mail::Message::Language::Japanese::Subject;
- return Mail::Message::Language::Japanese::Subject::is_reply($subject);
-}
-
-
-# Descriptions: assign a new thread id or
-# extract the existing thread-id from the subject
-# Arguments: OBJ($self) OBJ($msg)
-# $msg = Mail::Message object
-# Side Effects: a new thread_id may be assigned
-# Return Value: none
-sub assign
-{
- my ($self, $msg) = @_;
- my $header = $msg->whole_message_header();
- my $subject = $header->get('subject');
- my $is_reply = _is_reply($subject);
-
- # XXX-TODO: who validate $thread_id regexp
- # XXX-TODO: since $thread_id is given from outside.
- # 1. try to extract $thread_id from header
- my $thread_id = $self->_extract_thread_id_in_subject($header);
- unless ($thread_id) {
- # If we fail to pick up thread id from subject,
- # we try to speculate id from other fields in header.
- $thread_id = $self->_speculate_thread_id_from_header($header);
- if ($thread_id) {
- $is_reply = 1; # message already have thread_id, so replied one?
- $self->set_thread_id($thread_id);
- $self->log("speculated id=$thread_id");
- }
- else {
- $self->log("(debug) fail to spelucate thread_id") if $debug;
- }
- }
-
- # 2. check "X-Thread-Pragma:" field,
- # we ignore this mail if the pragma is specified as "ignore".
- if (defined $header->get('x-thread-pragma')) {
- my $pragma = $header->get('x-thread-pragma') || '';
- if ($pragma =~ /ignore/io) {
- $self->{ _pragma } = 'ignore';
- $self->_append_thread_status_info("ignored");
- return undef;
- }
- }
-
- # 3. if the header has some thread_id,
- # we do not rewrite the subject but save the extracted $thread_id.
- if ($is_reply && $thread_id) {
- $self->log("reply message with thread_id=$thread_id");
- $self->set_thread_id($thread_id);
- $self->set_thread_status('analyzed');
- $self->_append_thread_status_info('analyzed');
- }
- elsif ($thread_id) {
- $self->log("message with thread_id=$thread_id but not reply");
- $self->set_thread_id($thread_id);
- $self->_append_thread_status_info("found");
- }
- else {
- $self->log("message without thread_id") if $debug;
-
- my $id = $self->_assign_new_thread_id_number();
-
- # side effect:
- # define $self->{ _thread_subject_tag } and $self->{ _thread_id }
- my $thread_id = $self->_create_thread_id_strings($id);
- $self->set_thread_id($thread_id);
- $self->_append_thread_status_info("newly assigned");
- }
-}
-
-
-# Descriptions: assign new thread_id
-# Arguments: OBJ($self)
-# Side Effects: increment id
-# Return Value: NUM
-sub _assign_new_thread_id_number
-{
- my ($self) = @_;
- my $id = 0;
-
- # assign a new thread number for a new message
- if (1) {
- # unique but non sequential number
- $id = $self->{ _config }->{ article_id };
- }
- else {
- # incremental number
- $id = $self->increment_id();
- }
-
- $self->log("assign thread_id=$id") if $debug;
- return $id;
-}
-
-
-# Descriptions: update $self->{ _status_info }
-# Arguments: OBJ($self) STR($s)
-# Side Effects: update $self->{ _status_info }
-# Return Value: STR
-sub _append_thread_status_info
-{
- my ($self, $s) = @_;
- $self->{ _status_info } .= $self->{ _status_info } ? " -> ".$s : $s;
-}
-
-
-=head2 get_thread_status()
-
-get thread status.
-
-=head2 set_thread_status($status)
-
-set thread status.
-
-=cut
-
-
-# Descriptions: get thread status
-# Arguments: OBJ($self)
-# Side Effects: none
-# Return Value: STR
-sub get_thread_status
-{
- my ($self) = @_;
- return(defined $self->{ _status } ? $self->{ _status } : undef);
-}
-
-
-# Descriptions: set thread status
-# Arguments: OBJ($self) STR($thread_status)
-# Side Effects: none
-# Return Value: STR
-sub set_thread_status
-{
- my ($self, $thread_status) = @_;
- $self->{ _status } = $thread_status;
- return $thread_status;
-}
-
-
-=head2 update_thread_status($msg)
-
-ignore this procedure if "ignore" pragma is specified.
-
-update status to "close" if "close" pragma or "close" commmand in the
-message is found.
-
-=cut
-
-
-# Descriptions: update thread status
-# Arguments: OBJ($self) OBJ($msg)
-# Side Effects: update database
-# Return Value: none
-sub update_thread_status
-{
- my ($self, $msg) = @_;
- my $content = '';
- my $subject = '';
- my $pragma = '';
-
- if (defined $self->{ _pragma }) {
- return if $self->{ _pragma } eq 'ignore';
- }
-
- unless (ref($msg) eq 'Mail::Message') {
- croak("invalid object");
- }
-
- # filter messages of some class
- if (defined $self->{ _filterlist }) {
- if ($self->_is_ignore($msg)) {
- $self->log("this thread should be ignored");
- $pragma = "close";
- }
- }
-
- my $header = $msg->whole_message_header();
- my $textmsg = $msg->find_first_plaintext_message();
- $content = $textmsg->message_text() if defined $textmsg;
- $subject = $header->get('subject') || '';
- $pragma = $header->get('x-thread-pragma') || $pragma || '';
-
- if ($pragma =~ /close/ ||
- $content =~ /^\s*close/ ||
- $subject =~ /^\s*close/) {
- $self->set_thread_status("close");
- $self->_append_thread_status_info("closed");
- $self->log("thread is closed");
- }
- else {
- $self->log("thread status not changed");
- }
-}
-
-
-# Descriptions: check filter whether this $msg should be ignored or not.
-# Arguments: OBJ($self) OBJ($msg)
-# Side Effects: none
-# Return Value: 1 or 0
-sub _is_ignore
-{
- my ($self, $msg) = @_;
- my ($header, $textmsg, $content);
- my ($field, $rule);
- my $filterlist = $self->{ _filterlist };
-
- $header = $msg->whole_message_header();
- $textmsg = $msg->find_first_plaintext_message();
- $content = $textmsg->message_text() if defined $textmsg;
-
- # check header
- while (($field, $rule) = each %$filterlist) {
- if (defined $header->get($field)) {
- my $value = $header->get($field);
- if ($debug) {
- print STDERR "ignore $field: $value\n" if $value =~ /$rule/m;
- }
- return 1 if $value =~ /$rule/;
- }
- }
-
- return 0;
-}
-
-
-=head2 get_thread_id()
-
-get thread_id in object ($self->{ _thread_id }).
-
-=head2 set_thread_id($thread_id)
-
-set thread_id in object ($self->{ _thread_id }).
-
-=cut
-
-
-# Descriptions: get thread_id in object ($self->{ _thread_id }).
-# Arguments: OBJ($self)
-# Side Effects: none.
-# Return Value: STR or UNDEF
-sub get_thread_id
-{
- my ($self) = @_;
- return(defined $self->{ _thread_id } ? $self->{ _thread_id } : undef);
-}
-
-
-# Descriptions: set thread_id
-# Arguments: OBJ($self) STR($thread_id)
-# Side Effects: update $self->{ _thread_id }.
-# Return Value: STR
-sub set_thread_id
-{
- my ($self, $thread_id) = @_;
- $self->{ _thread_id } = $thread_id;
- return $thread_id;
-}
-
-
-# Descriptions: create regexp for a subject tag, for example
-# "[%s %05d]" => "\[\S+ \d+\]"
-# Arguments: STR($s)
-# XXX non OO type function
-# Side Effects: none
-# Return Value: STR(a regexp for the given tag)
-sub _regexp_compile
-{
- my ($s) = @_;
-
- $s = quotemeta( $s );
- $s =~ s@\\\%@\%@g;
- $s =~ s@\%s@\\S+@g;
- $s =~ s@\%d@\\d+@g;
- $s =~ s@\%0\d+d@\\d+@g;
- $s =~ s@\%\d+d@\\d+@g;
- $s =~ s@\%\-\d+d@\\d+@g;
-
- # quote for regexp substitute: [ something ] -> \[ something \]
- # $s =~ s/^(.)/quotemeta($1)/e;
- # $s =~ s/(.)$/quotemeta($1)/e;
-
- return $s;
-}
-
-
-# Descriptions: extract message-id list and return it.
-# Arguments: OBJ($header)
-# function not OO
-# Side Effects: none
-# Return Value: ARRAY_HASH
-sub _extract_message_id_references
-{
- my ($header) = @_;
- my (@addrs, @r, %uniq) = ();
-
- # XXX-TODO: Mail::Message should provide this function ?
-
- use Mail::Address;
-
- if (defined $header->get('in-reply-to')) {
- my $buf = $header->get('in-reply-to');
- push(@addrs, Mail::Address->parse($buf));
- }
-
- if (defined $header->get('references')) {
- my $buf = $header->get('references');
- push(@addrs, Mail::Address->parse($buf));
- }
-
- for my $addr (@addrs) {
- my $a = $addr->address;
- unless (defined $uniq{ $a } && $uniq{ $a }) {
- # RFC822 says msg-id = "<" addr-spec ">" ; Unique message id
- push(@r, "<".$addr->address.">");
- $uniq{ $a } = 1;
- }
- }
-
- return \@r;
-}
-
-
-# Descriptions: extract thread_id in Subject:
-# Arguments: OBJ($self) OBJ($header)
-# Side Effects: none
-# Return Value: STR or 0
-sub _extract_thread_id_in_subject
-{
- my ($self, $header) = @_;
- my $config = $self->{ _config };
- my $tag = $config->{ thread_subject_tag } || '';
- my $loctype = $config->{ thread_subject_tag_location } || 'appended';
- my $subject = $header->get('subject') || '';
- my $regexp = _regexp_compile($tag);
-
- # Subject: ... [thread_id]
- if (($loctype eq 'appended') && ($subject =~ /($regexp)\s*$/)) {
- my $id = $1;
- $id =~ s/^(\[|\(|\{)//;
- $id =~ s/(\]|\)|\})$//;
- return $id;
- }
- # XXX incomplete, we check subject after cutting off "Re:" et. al.
- # Subject: [thread_id] ...
- # Subject: Re: [thread_id] ...
- elsif (($loctype eq 'prepended') && ($subject =~ /^\s*($regexp)/)) {
- my $id = $1;
- $id =~ s/^(\[|\(|\{)//;
- $id =~ s/(\]|\)|\})$//;
- return $id;
- }
- else {
- $self->log("no thread id /$regexp/ in subject") if $debug;
- return 0;
- }
-}
-
-
-# Descriptions:
-# For example, consider a posting to both elena ML and
-# rudo (DM) from kenken.
-#
-# From: kenken
-# To: elena-ml
-# Cc: rudo
-#
-# The reply to this DM (direct message) from rudo is
-#
-# From: rudo
-# To: elena-ml
-#
-# This reply message has no thread_id since the
-# message from kenken to rudo comes directly from
-# kenken not through fml driver. In this case, we
-# try to speculdate the reply relation and the
-# thread_id of this thread by using _
-# speculate_thread_id_from_header().
-#
-# Arguments: OBJ($self) OBJ($header)
-# Side Effects: none
-# Return Value: STR(message id)
-sub _speculate_thread_id_from_header
-{
- my ($self, $header) = @_;
- my $midlist = _extract_message_id_references( $header );
- my $result = '';
-
- if (defined $midlist) {
- $self->db_open();
-
- # prepare hash table tied to db_dir/*db's
- my $rh = $self->{ _hash_table };
-
- MSGID_LIST:
- for my $mid (@$midlist) {
- $result = $rh->{ _message_id }->{ $mid };
- last MSGID_LIST if $result;
- }
-
- $self->db_close();
- }
-
- if ($debug) {
- $self->log("(debug) not speculated") unless $result;
- }
- $result;
-}
-
-
-# Descriptions: create thread_id
-# Arguments: OBJ($self) STR($id)
-# Side Effects: update $self->{ _thread_subject_tag }
-# Return Value: STR(thread_id string)
-sub _create_thread_id_strings
-{
- my ($self, $id) = @_;
- my $config = $self->{ _config };
-
- # thread_id appeared in subject: field
- my $subject_tag = $config->{ thread_subject_tag };
- $self->{ _thread_subject_tag } = sprintf($subject_tag, $id);
-
- # thread_id used as primary key
- my $id_syntax = $config->{ thread_id_syntax };
- return sprintf($id_syntax, $id);
-}
-
-
-=head2 update_db($msg)
-
-update database.
-
-=cut
-
-
-# Descriptions: top level dispatcher to drive database update
-# Arguments: OBJ($self) OBJ($msg)
-# Side Effects: update databases
-# Return Value: none
-sub update_db
-{
- my ($self, $msg) = @_;
- my $config = $self->{ _config };
- my $ml_name = $config->{ ml_name };
-
- if (defined $self->{ _pragma }) {
- return if $self->{ _pragma } eq 'ignore';
- }
-
- $self->db_open();
-
- # save $ticke_id et.al. in db_dir/$ml_name
- $self->_update_db($msg);
-
- $self->prepare_history_info($msg) if $self->{ _is_rewrite_header };
-
- # save cross reference pointers among $ml_name
- $self->_update_index_db();
-
- $self->db_close();
-}
-
-
-# Descriptions: speculate unixtime from header
-# Arguments: OBJ($msg)
-# Side Effects: none
-# Return Value: NUM(unix time)
-sub _speculate_time
-{
- my ($msg) = @_;
- my $header = $msg->whole_message_header;
-
- if (defined $header->get('date')) {
- use Mail::Message::Date;
- my $obj = new Mail::Message::Date;
- return $obj->date_to_unixtime($header->get('date'));
- }
- else {
- return time;
- }
-}
-
-
-# Descriptions: update database
-# Arguments: OBJ($self) OBJ($msg)
-# Side Effects: update database
-# Return Value: STR
-sub _update_db
-{
- my ($self, $msg) = @_;
- my $config = $self->{ _config };
- my $article_id = $config->{ article_id };
- my $thread_id = $self->get_thread_id();
-
- # 0. logging
- $self->log("article_id=$article_id thread_id=$thread_id") if $debug;
-
- # prepare hash table tied to db_dir/*db's
- my $rh = $self->{ _hash_table };
-
- # check
- if (defined $rh->{ _thread_id }->{ $article_id }) {
- print STDERR "_update_db.ignore id=$article_id\n" if $debug;
- return;
- }
-
- # 1.
- $rh->{ _thread_id }->{ $article_id } = $thread_id;
- $rh->{ _date }->{ $article_id } = _speculate_time($msg);
- $rh->{ _articles }->{ $thread_id } .= $article_id . " ";
-
- # 2. record the sender information
- my $header = $msg->whole_message_header;
- $rh->{ _sender }->{ $article_id } = $header->get('from');
-
- # 3. update status information
- if (defined $self->get_thread_status()) {
- my $status = $self->get_thread_status();
- $self->_set_status($thread_id, $status);
- }
- else {
- # set the default status value for the first time.
- unless (defined $rh->{ _status }->{ $thread_id }) {
- $self->_set_status($thread_id, 'open');
- }
- }
-
- # 4. save optional/additional information
- # message_id hash is { message_id => thread_id };
- # RFC822 says msg-id = "<" addr-spec ">" ; Unique message id
- my $mid = $header->get('message-id'); $mid =~ s/[\n\s]*$//;
- if ($mid eq "") {
- print STDERR "missing message-id $thread_id\n" if $debug;
- return;
- }
- $rh->{ _message_id }->{ $mid } = $thread_id;
-}
-
-
-# Descriptions: register myself to index_db for further reference
-# among mailing lists
-# Arguments: OBJ($self)
-# Side Effects: update object
-# Return Value: STR
-sub _update_index_db
-{
- my ($self) = @_;
- my $config = $self->{ _config };
- my $thread_id = $self->get_thread_id();
- my $rh = $self->{ _hash_table };
- my $ml_name = $config->{ ml_name };
-
- my $ref = $rh->{ _index }->{ $thread_id } || '';
- if ($ref !~ /^$ml_name|\s$ml_name\s|$ml_name$/) {
- $rh->{ _index }->{ $thread_id } .= $ml_name." ";
- }
-}
-
-
-=head1 CODING STYLE
-
-See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-
-=head1 AUTHOR
-
-Ken'ichi Fukamachi
-
-=head1 COPYRIGHT
-
-Copyright (C) 2001,2002,2003 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::Analyze first appeared in fml8 mailing list driver package.
-See C<http://www.fml.org/> for more details.
-
-=cut
-
-
-1;
diff --git a/fml/lib/Mail/ThreadTrack/DB.pm b/fml/lib/Mail/ThreadTrack/DB.pm
deleted file mode 100644
index a7831861..00000000
--- a/fml/lib/Mail/ThreadTrack/DB.pm
+++ /dev/null
@@ -1,321 +0,0 @@
-#-*- perl -*-
-#
-# Copyright (C) 2001,2002,2003 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: DB.pm,v 1.33 2003/08/23 04:35:49 fukachan Exp $
-#
-
-package Mail::ThreadTrack::DB;
-use strict;
-use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD);
-use Carp;
-
-my $debug = 0;
-
-=head1 NAME
-
-Mail::ThreadTrack::DB - database access.
-
-=head1 SYNOPSIS
-
-=head1 DESCRIPTION
-
-=head1 METHODS
-
-=cut
-
-=head2 db_open()
-
-open database.
-It uses tie() to bind a hash to a DB file.
-Our thread model uses several DB files such as
-C<%thread_id>,
-C<%date>,
-C<%status>,
-C<%sender>,
-C<%articles>,
-C<%message_id>
-and
-C<%index>.
-
-=head2 db_close()
-
-untie() the corresponding hashes opened by C<db_open()>.
-
-=cut
-
-my @kind_of_databases = qw(thread_id date status sender articles
- message_id);
-
-
-# Descriptions: open database by tie()
-# Arguments: OBJ($self)
-# Side Effects: $self->{ _hash_table } initialized.
-# Return Value: none
-sub db_open
-{
- my ($self) = @_;
- my $db_type = $self->{ config }->{ db_type } || 'AnyDBM_File';
- my $db_dir = $self->{ _db_dir };
- my $file_mode = $self->{ _file_mode } || 0644;
-
- use File::Spec;
- eval qq{ use $db_type; use Fcntl;};
- unless ($@) {
- for my $db (@kind_of_databases) {
- my $file = File::Spec->catfile($db_dir, $db);
- my $str = qq{
- my \%$db = ();
- tie \%$db, \$db_type, \$file, O_RDWR|O_CREAT, $file_mode;
- \$self->{ _hash_table }->{ _$db } = \\\%$db;
- };
- eval $str;
- croak($@) if $@;
- }
-
- my %index = ();
- my $index_file = $self->{ _index_db };
- eval q{
- tie %index, $db_type, $index_file, O_RDWR|O_CREAT, $file_mode;
- $self->{ _hash_table }->{ _index } = \%index;
- };
- croak($@) if $@;
- }
- else {
- croak("failed to \"use $db_type\"");
- }
-
- 1;
-}
-
-
-# Descriptions: clear database
-# Arguments: OBJ($self)
-# Side Effects: update database
-# Return Value: none
-sub db_clear
-{
- my ($self) = @_;
- my $db_dir = '';
-
- $db_dir = $self->{ _db_dir };
- _db_clear($db_dir) if -d $db_dir;
-
- $db_dir = $self->{ _db_base_dir };
- _db_clear($db_dir) if -d $db_dir;
-}
-
-
-# Descriptions: clear database
-# Arguments: STR($db_dir)
-# Side Effects: clear database, remove file if needed
-# Return Value: none
-sub _db_clear
-{
- my ($db_dir) = @_;
-
- eval q{
- use DirHandle;
- use File::Spec;
- my $dh = new DirHandle $db_dir;
-
- if (defined $dh) {
- my $f = '';
- while (defined($f = $dh->read)) {
- next if $f =~ /^\./;
- my $file = File::Spec->catfile($db_dir, $f);
- if (-f $file) {
- unlink $file;
- print STDERR "removed $file\n" unless -f $file;
- }
- }
- $dh->close;
- }
- };
- croak($@) if $@;
-}
-
-
-# Descriptions: close database by untie()
-# Arguments: OBJ($self)
-# Side Effects: none
-# Return Value: none
-sub db_close
-{
- my ($self) = @_;
-
- for my $db (@kind_of_databases) {
- my $str = qq{
- my \$${db} = \$self->{ _hash_table }->{ _$db };
- untie \%\$${db};
- };
- eval $str;
- croak($@) if $@;
- }
-
- my $index = $self->{ _hash_table }->{ _index };
- untie %$index;
-}
-
-
-=head2 db_mkdb($min, $max)
-
-remake database.
-
-=cut
-
-
-# Descriptions: remake database for messages from $min_id to $max_id
-# Arguments: OBJ($self) NUM($min_id) NUM($max_id)
-# Side Effects: remake database
-# Return Value: none
-sub db_mkdb
-{
- my ($self, $min_id, $max_id) = @_;
- my $config = $self->{ _config };
- my $spool_dir = $config->{ spool_dir };
- my $saved_args = $self->{ _saved_args }; # original $args
-
- return undef unless (defined $min_id && defined $max_id);
-
- use Mail::Message;
- use File::Spec;
-
- my $count = 0;
- my ($fh, $file, $msg);
- print STDERR "db_mkdb: $min_id -> $max_id\n" if $debug;
-
- ID:
- for my $id ( $min_id .. $max_id ) {
- print STDERR "." if $count++ % 10 == 0;
- print STDERR "process $id\n" if $debug;
-
- # XXX-TODO: this code is workaround, we should create more clever way.
- # XXX-TODO: overwrite (tricky)
- $self->{ _config }->{ article_id } = $id;
-
- # parse article and analyze it.
- $file = $self->filepath({
- base_dir => $spool_dir,
- id => $id,
- });
-
- $fh = new FileHandle $file;
- if (defined $fh) {
- my $msg = Mail::Message->parse({ fd => $fh });
- $self->analyze($msg);
-
- # XXX-TODO: workaround, we should create more clever way.
- # XXX-TODO: remove current status (tricky ;)
- delete $self->{ _status };
- }
- }
- print STDERR "\n" if $count > 0;
-}
-
-
-=head2 db_dump([$type])
-
-dump hash as text.
-dump status database if $type is not specified.
-
-=cut
-
-
-# Descriptions: dump data for database $type
-# Arguments: OBJ($self) STR($type)
-# Side Effects: none
-# Return Value: none
-sub db_dump
-{
- my ($self, $type) = @_;
- my $db_type = "_" . ( defined $type ? $type : 'status' );
- my $rh = $self->{ _hash_table }->{ $db_type };
-
- my ($k, $v);
- while (($k, $v) = each %$rh) {
- printf "%-20s %s\n", $k, $v;
- }
-}
-
-
-=head2 db_hash( $type )
-
-return HASH REFERENCE for specified database $type.
-
-=cut
-
-
-# Descriptions: get HASH REFERENCE for specified $type.
-# Arguments: OBJ($self) STR($db_type)
-# Side Effects: none
-# Return Value: HASH_REF or UNDEF
-sub db_hash
-{
- my ($self, $db_type) = @_;
- my $type = "_" . $db_type;
-
- if (defined $self->{ _hash_table }->{ $type }) {
- return $self->{ _hash_table }->{ $type };
- }
- else {
- return undef;
- }
-}
-
-
-=head2 db_last_modified()
-
-return the last modified time of our dateabase as unix time.
-This time is the latest modified time among all database files.
-
-=cut
-
-
-# Descriptions: return the last modified time (unix time) of database
-# Arguments: OBJ($self) STR($db_type)
-# Side Effects: none
-# Return Value: STR or UNDEF
-sub db_last_modified
-{
- my ($self, $db_type) = @_;
- my $db_dir = $self->{ _db_dir };
- my $last_modified = 0;
-
- # XXX-TODO: we supporse Berkeley DB. fix it.
- use File::Spec;
- my $file = File::Spec->catfile($db_dir, "date.db");
- if (-f $file) {
- $last_modified = (stat($file))[8];
- }
-
- return $last_modified;
-}
-
-
-=head1 CODING STYLE
-
-See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-
-=head1 AUTHOR
-
-Ken'ichi Fukamachi
-
-=head1 COPYRIGHT
-
-Copyright (C) 2001,2002,2003 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::DB first appeared in fml8 mailing list driver package.
-See C<http://www.fml.org/> for more details.
-
-=cut
-
-
-1;
diff --git a/fml/lib/Mail/ThreadTrack/HeaderRewrite.pm b/fml/lib/Mail/ThreadTrack/HeaderRewrite.pm
deleted file mode 100644
index 5b47445c..00000000
--- a/fml/lib/Mail/ThreadTrack/HeaderRewrite.pm
+++ /dev/null
@@ -1,133 +0,0 @@
-#-*- perl -*-
-#
-# Copyright (C) 2001,2002,2003 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: HeaderRewrite.pm,v 1.14 2003/08/23 04:35:49 fukachan Exp $
-#
-
-package Mail::ThreadTrack::HeaderRewrite;
-use strict;
-use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD);
-use Carp;
-
-=head1 NAME
-
-Mail::ThreadTrack::HeaderRewrite - header manipulation
-
-=head1 SYNOPSIS
-
-=head1 DESCRIPTION
-
-=head1 METHODS
-
-=head2 rewrite_header($msg)
-
-C<$msg> is Mail::Message object.
-
-=cut
-
-
-# Descriptions: add thread track info into $msg where
-# $msg is Mail::Message object.
-# Arguments: OBJ($self) OBJ($msg)
-# Side Effects: modify $msg header
-# Return Value: none
-sub rewrite_header
-{
- my ($self, $msg) = @_;
- my $config = $self->{ _config };
- my $loctype = $config->{ thread_subject_tag_location } || 'appended';
- my $header = $msg->whole_message_header();
- my $tag = $self->{ _thread_subject_tag } || '';
-
- # append the thread tag to the subject
- if (defined $header->get('subject')) {
- my $subject = $header->get('subject');
-
- if ($loctype eq 'appended' && $tag) {
- $header->replace('subject', $subject ." ". $tag);
- }
- elsif ($loctype eq 'prepended' && $tag) {
- $header->replace('subject', $tag ." ". $subject);
- }
- else {
- $self->log("unknown thread_subject_tag_location type");
- }
-
- if (defined $self->{ _status_info }) {
- $header->add('X-Thread-Status', $self->{ _status_info });
- }
-
- if (defined $self->{ _thread_id }) {
- $header->add('X-Thread-ID', $self->{ _thread_id });
- }
-
- if (defined $self->{ _status_history }) {
- $header->add('X-Thread-History', $self->{ _status_history });
- }
- }
-}
-
-
-# Descriptions: prepare history infomation for further header rewriting.
-# Arguments: OBJ($self) OBJ($msg)
-# Side Effects: update $self->{ _status_history }
-# Return Value: none
-sub prepare_history_info
-{
- my ($self, $msg) = @_;
- my $thread_id = $self->get_thread_id();
-
- # prepare hash table tied to db_dir/*db's
- my $rh = $self->{ _hash_table };
-
- if (defined $rh->{ _articles }->{ $thread_id }) {
- my $buf = '';
- my (@aid) = split(/\s+/, $rh->{ _articles }->{ $thread_id });
- my $sender = $rh->{ _sender }->{ $aid[0] };
- my $when = $rh->{ _date }->{ $aid[0] };
-
- # clean up
- $sender =~ s/[\s\n]*$//;
- $when =~ s/[\s\n]*$//;
-
- use Mail::Message::Date;
- $when = Mail::Message::Date->new($when)->mail_header_style();
-
- # XXX-TODO: validate $aid[0], $sender, $when, @aid.
- $buf .= "\t\n";
- $buf .= "\tthis thread is opended at article $aid[0]\n";
- $buf .= "\tby $sender\n";
- $buf .= "\ton $when\n";
- $buf .= "\tarticle references: @aid\n";
- $self->{ _status_history } = $buf;
- }
-}
-
-
-=head1 CODING STYLE
-
-See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-
-=head1 AUTHOR
-
-Ken'ichi Fukamachi
-
-=head1 COPYRIGHT
-
-Copyright (C) 2001,2002,2003 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::HeaderRewrite first appeared in fml8 mailing list driver package.
-See C<http://www.fml.org/> for more details.
-
-=cut
-
-
-1;
diff --git a/fml/lib/Mail/ThreadTrack/Print.pm b/fml/lib/Mail/ThreadTrack/Print.pm
deleted file mode 100644
index c8b08bfc..00000000
--- a/fml/lib/Mail/ThreadTrack/Print.pm
+++ /dev/null
@@ -1,419 +0,0 @@
-#-*- perl -*-
-#
-# Copyright (C) 2001,2002,2004 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.27 2002/12/22 03:21:33 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([ @opts ])
-
-show todo list without article summary.
-
-=cut
-
-
-# Descriptions: show todo list without article summary.
-# Arguments: OBJ($self) VARARGS(@opts)
-# 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([ @opts ])
-
-show the thread summary, which is todo list C<with> article summary.
-
-Each row that C<show_summary()> returns has a set of
-C<date>, C<age>, C<status>, C<thread-id> and
-C<articles>, which is a list of articles with the thread-id.
-
-list() shows 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
-
-summary() shows the todo list above and article summaries.
-
-=cut
-
-
-# Descriptions: show todo list with article summary.
-# Arguments: OBJ($self) VARARGS(@opts)
-# 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([ @opts ])
-
-show a chain of a few lines summary for articles in each thread.
-This summary is a collection of short summary of articles in one thread.
-
-=cut
-
-
-# Descriptions: show a chain of summaries for each thread.
-# Arguments: OBJ($self) VARARGS(@opts)
-# 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 if needed.
-# Arguments: OBJ($thread) 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) {
- # XXX-TODO: $thread->sort() method should accept the order ?
- $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;
- }
-
- # XXX thread summary == todo list
- $thread->_print_thread_summary($thread_id_list);
-
- # XXX message summary == brief summary of articles.
- if ($option->{ mode } eq 'summary') {
- $thread->_print_message_summary($thread_id_list);
- }
- }
-}
-
-
-# Descriptions: show thread summary (without article 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 };
-
- # XXX-TODO: who care for output mode ? (e.g. against CSS).
- $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 ARRAY_REF 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 }) {
- # XXX-TODO: validate $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 = $self->filepath({
- base_dir => $spool_dir,
- id => $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/<BR>\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/&/&amp;/g;
- $str =~ s/</&lt;/g;
- $str =~ s/>/&gt;/g;
- $str =~ s/\"/&quot;/g;
-
- return $str;
-}
-
-
-=head1 CODING STYLE
-
-See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-
-=head1 AUTHOR
-
-Ken'ichi Fukamachi
-
-=head1 COPYRIGHT
-
-Copyright (C) 2001,2002,2004 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 first appeared in fml8 mailing list driver package.
-See C<http://www.fml.org/> for more details.
-
-=cut
-
-
-1;
diff --git a/fml/lib/Mail/ThreadTrack/Print/HTML.pm b/fml/lib/Mail/ThreadTrack/Print/HTML.pm
deleted file mode 100644
index 220c6e09..00000000
--- a/fml/lib/Mail/ThreadTrack/Print/HTML.pm
+++ /dev/null
@@ -1,291 +0,0 @@
-#-*- perl -*-
-#
-# Copyright (C) 2001,2002,2003 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: HTML.pm,v 1.17 2003/02/11 11:22:56 fukachan Exp $
-#
-
-package Mail::ThreadTrack::Print::HTML;
-
-use strict;
-use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD);
-use Carp;
-
-
-=head1 NAME
-
-Mail::ThreadTrack::Print::HTML - print thread summary as HTML
-
-=head1 SYNOPSIS
-
-See C<Mail::ThreadTrack::Print> for usage of this subclass.
-
-=head1 DESCRIPTION
-
-See C<Mail::ThreadTrack::Print> for usage of this subclass.
-
-=head1 METHODS
-
-=head2 show_articles_in_thread(thread_id)
-
-show articles as HTML in this thread.
-
-=cut
-
-
-use CGI qw/:standard/;
-use Mail::ThreadTrack::Print::Utils qw(decode_mime_string STR2EUC);
-
-
-# Descriptions: show articles as HTML in this thread
-# Arguments: OBJ($self) STR($thread_id)
-# Side Effects: none
-# Return Value: none
-sub show_articles_in_thread
-{
- my ($self, $thread_id) = @_;
- my $mode = $self->get_mode || 'text';
- my $config = $self->{ _config };
- my $spool_dir = $config->{ spool_dir };
-
- my $articles = $self->{ _hash_table }->{ _articles }->{ $thread_id };
-
- # XXX-TODO: who validates $thread_id ?
- print "<B>";
- print "show contents related with thread_id=$thread_id\n";
- print "</B>";
- print "<HR>";
- print "<PRE>\n";
-
- if (defined($articles) && defined($spool_dir) && -d $spool_dir) {
- use FileHandle;
-
- my $s = '';
- for my $article (split(/\s+/, $articles)) {
- my $file = $self->filepath({
- base_dir => $spool_dir,
- id => $article,
- });
-
- # XXX-TODO: care for non Japanese char(s).
- # XXX-TODO: to avoid CSS bug, convert all special char(s).
- # XXX-TODO: create method safe_html_string() in Mail::Message ?
- if (-f $file) {
- my $fh = new FileHandle $file;
-
- if (defined $fh) {
- my $buf;
-
- while (defined($buf = $fh->getline())) {
- # ignore header part.
- next if 1 .. $buf =~ /^$/o;
-
- $s = STR2EUC($buf);
- $s =~ s/&/&amp;/g;
- $s =~ s/</&lt;/g;
- $s =~ s/>/&gt;/g;
- $s =~ s/\"/&quot;/g;
- print $s;
- }
- $fh->close;
- }
- }
- }
- }
-
- print "</PRE>";
-}
-
-
-# Descriptions: show guide
-# Arguments: OBJ($self) HASH_REF($args)
-# Side Effects: none
-# Return Value: none
-sub __start_thread_summary
-{
- my ($self, $args) = @_;
- my $config = $self->{ _config };
- my $ml_name = $config->{ ml_name };
- my $fd = $self->{ _fd } || \*STDOUT;
- my $action = $curproc->safe_cgi_action_name();
- my $target = '_top';
-
- # statistics
- if (defined $self->{ _ticket_id_stat }) {
- my $stat = $self->{ _ticket_id_stat };
- for my $key ('open', 'analyzed', 'closed') {
- print $fd "$key: ";
- print $fd defined $stat->{ $key } ? $stat->{ $key } : 0;
- print $fd ", ";
- }
- print $fd br, "\n";
- }
-
- # XXX-TODO: validate $action ?
- print $fd start_form(-action=>$action, -target=>$target);
- print $fd submit(-name => 'submit');
- print $fd reset(-name => 'reset');
- print $fd "\n";
-
- # XXX-TODO: validate $ml_name ?
- print $fd hidden(-name => 'ml_name',
- -default => [ $ml_name ],
- ), "\n";
-
- param('action', 'change_status'); # we need to override
- print $fd hidden(-name => 'action',
- -default => [ 'change_status ' ],
- ), "\n";
-
- print $fd "<TABLE BORDER=4>\n";
- print $fd "<TD>id\n";
- print $fd "<TD>change\n";
- print $fd "<TD>summary\n";
- print $fd "<TD>age\n";
- print $fd "<TD>status\n";
-}
-
-
-# Descriptions: finalize thread list.
-# close TABLE tag.
-# Arguments: OBJ($self) HASH_REF($args)
-# Side Effects: none
-# Return Value: none
-sub __end_thread_summary
-{
- my ($self, $args) = @_;
- my $fd = $self->{ _fd } || \*STDOUT;
-
- print $fd "</TABLE>\n";
-
- print submit(-name => 'submit');
- print reset(-name => 'reset');
- print $fd end_form;
-}
-
-
-# Descriptions: This shows summary on C<$thread_id> in HTML language.
-# It is used in C<FML::CGI::ThreadSystem>.
-# Arguments: OBJ($self) HASH_REF($optargs)
-# Side Effects: none
-# Return Value: none
-sub __print_thread_summary
-{
- my ($self, $optargs) = @_;
- my $config = $self->{ _config };
- my $ml_name = $config->{ ml_name };
- my $spool_dir = $config->{ spool_dir };
- my $action = $curproc->safe_cgi_action_name();
- my $target = $config->{ thread_cgi_target_window } || '_top';
-
- my $date = $optargs->{ date };
- my $age = $optargs->{ age };
- my $status = $optargs->{ status };
- my $tid = $optargs->{ thread_id };
- my $articles = $optargs->{ articles };
- my $aid = (split(/\s+/, $articles))[0];
-
- # do nothing if the $thread_id is unknown.
- return unless $tid;
-
- # XXX-TODO: validate $action, $ml_name, $aid ...
- # <FORM ACTION=> ..>
- my $xtid = CGI::escape($tid);
- $action = "${action}?ml_name=${ml_name}&article_id=$aid";
-
- $self->{ _table_count } = 1 unless defined $self->{ _table_count };
- if (($self->{ _table_count }++ % 5) == 0) {
- print "<TR>\n<TD>\n";
- print submit(-name => 'submit');
- print reset(-name => 'reset');
- }
-
- print "<TR>\n";
-
- # XXX-TODO: validate $msg_base_url ?
- # show articles in this thread id
- print "<TD>";
- if (defined $config->{ msg_base_url }) {
- my $msg_base_url = $config->{ msg_base_url };
- my $url = "$msg_base_url/msg$aid.html";
- print "<A HREF=\"$url\" TARGET=\"article\">\n";
- print $tid;
- print "\n</A>\n";
- }
- else {
- # XXX-TODO: validate $action ?
- print "<A HREF=\"$action&action=show\" TARGET=\"article\">\n";
- print $tid;
- print "\n</A>\n";
- }
-
- # action
- print "<TD>";
- my $name = "change_status.$tid";
- my $values = ["open", "analyzed", "closed"];
- my $default = $status;
- print radio_group(-name => $name,
- -values => $values,
- -default => $default,
- -linebreak => 'true',
- );
-
- # message (article) brief summary
- print "<TD>";
- if (defined $articles) {
- $aid = (split(/\s+/, $articles))[0];
- my $f = $self->filepath({
- base_dir => $spool_dir,
- id => $aid,
- });
- if (-f $f) {
- # XXX-TODO: care for non Japanese.
- my $buf = $self->message_summary($f);
- $self->print( STR2EUC($buf) );
- }
- }
-
- # addional information: age, status
- print "<TD>$age\n";
- print "<TD>$status\n";
-
- print "\n\n";
-}
-
-
-# Descriptions: dummy, defined for symmetry
-# Arguments: none
-# Side Effects: none
-# Return Value: none
-sub __print_message_summary
-{
- ;
-}
-
-
-=head1 CODING STYLE
-
-See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-
-=head1 AUTHOR
-
-Ken'ichi Fukamachi
-
-=head1 COPYRIGHT
-
-Copyright (C) 2001,2002,2003 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::HTML first appeared in fml8 mailing list driver package.
-See C<http://www.fml.org/> for more details.
-
-=cut
-
-
-1;
diff --git a/fml/lib/Mail/ThreadTrack/Print/Message.pm b/fml/lib/Mail/ThreadTrack/Print/Message.pm
deleted file mode 100644
index 7c61a63a..00000000
--- a/fml/lib/Mail/ThreadTrack/Print/Message.pm
+++ /dev/null
@@ -1,253 +0,0 @@
-#-*- perl -*-
-#
-# Copyright (C) 2001,2002,2003 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: Message.pm,v 1.9 2002/12/22 03:19:15 fukachan Exp $
-#
-
-package Mail::ThreadTrack::Print::Message;
-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::Message - summarize message et.al.
-
-=head1 SYNOPSIS
-
-See C<Mail::ThreadTrack::Print> for usage of this subclass.
-
-=head1 DESCRIPTION
-
-See C<Mail::ThreadTrack::Print> for usage of this subclass.
-
-=head1 METHODS
-
-=head2 message_summary($file)
-
-make message summary for specified $file (article).
-
-=cut
-
-
-# Descriptions: make summary of the specified $file (article).
-# Arguments: OBJ($self) STR($file)
-# Side Effects: none
-# Return Value: STR
-sub message_summary
-{
- my ($self, $file) = @_;
- my (@header) = ();
- my $msgbuf = '';
- my $line = $self->{ _article_summary_lines } || 3;
- my $mode = $self->get_mode || 'text';
- my $padding = $mode eq 'text' ? ' ' : '';
-
- use FileHandle;
- my $fh = new FileHandle $file;
-
- if (defined $fh) {
- my $buf;
-
- LINE:
- while ($buf = <$fh>) {
- # remove useless lines
- next LINE if $buf =~ /^\>/o;
- next LINE if $buf =~ /^\-/o;
-
- # header part
- if (1 .. $buf =~ /^$/o) {
- push(@header, $buf);
- }
- # body part
- else {
- next LINE if $buf =~ /^\s*$/o;
-
- # ignore mail header like patterns.
- next LINE if $buf =~ /^X-[-A-Za-z0-9]+:/io;
- next LINE if $buf =~ /^Return-[-A-Za-z0-9]+:/io;
- next LINE if $buf =~ /^Mime-[-A-Za-z0-9]+:/io;
- next LINE if $buf =~ /^Content-[-A-Za-z0-9]+:/io;
- next LINE if $buf =~ /^(To|From|Subject|Reply-To|Received):/io;
- next LINE if $buf =~ /^(Message-ID|Date):/io;
-
- # pick up effetive the first $line lines
- if (_is_valid_buf($buf)) {
- $line--;
- $msgbuf .= $padding . $buf;
- }
-
- last LINE if $line < 0;
- }
- }
-
- $fh->close();
-
- # XXX-TODO: WHO CARE FOR CSS ? return raw messages from here.
- # XXX-TODO: care for non Japanese.
- if (defined $self->{ _no_header_summary }) {
- return STR2EUC( $msgbuf );
- }
- else {
- use Mail::Header;
- my $header = new Mail::Header \@header;
- my $header_info = $self->header_summary({
- header => $header,
- padding => $padding,
- });
- return STR2EUC( $header_info ."\n". $msgbuf );
- }
- }
- else {
- return undef;
- }
-}
-
-
-# Descriptions: check if $str looks effective, not quotation et.al. ?
-# Arguments: STR($str)
-# Side Effects: none
-# Return Value: 1 or 0
-sub _is_valid_buf
-{
- my ($str) = @_;
- $str = STR2EUC( $str );
-
- if ($str =~ /^[\>\#\|\*\:\;\=]/o) {
- return 0;
- }
- elsif ($str =~ /^in /o) { # quotation ?
- return 0;
- }
- elsif ($str =~ /\w+\@\w+/o) { # mail address ?
- return 0;
- }
- elsif ($str =~ /^\S+\>/o) { # quotation ?
- return 0;
- }
-
- return 1;
-}
-
-
-# Descriptions: remove subject tag like string in $str e.g. [elena 100].
-# Arguments: STR($str)
-# Side Effects: none
-# Return Value: STR
-sub _delete_subject_tag_like_string
-{
- my ($str) = @_;
-
- if (defined $str) {
- # XXX-TODO: hmm, method-ify Mail::Message::Utils ?
- use Mail::Message::Utils;
- return Mail::Message::Utils::remove_subject_tag_like_string($str);
- }
- else {
- return undef;
- }
-}
-
-
-# Descriptions: make summary of header $args->{ header }.
-# Arguments: OBJ($self) HASH_REF($args)
-# Side Effects: none
-# Return Value: STR
-sub header_summary
-{
- my ($self, $args) = @_;
- my $date = $args->{ header }->get('date');
- my $from = $args->{ header }->get('from');
- my $subject = $args->{ header }->get('subject');
- my $padding = $args->{ padding } || ' ';
-
- # XXX-TODO: care for non Japanese.
- if (defined $subject) {
- $subject = decode_mime_string($subject, { charset => 'euc-japan' });
- $subject =~ s/\n/ /g;
- $subject = _delete_subject_tag_like_string($subject);
- $subject =~ s/[\s\n]*$//g;
- }
-
- if (defined $from) {
- $from = $self->_who_of_address( $from );
- $from =~ s/\n/ /g;
- $from =~ s/[\s\n]*$//g;
- }
-
- # XXX-TODO: WHO CARE FOR CSS ? return raw messages from here.
- # XXX-TODO: care for non Japanese.
- # return buffer
- my $r = $padding. $date;
- $r .= $padding. "$subject, $from\n";
- return STR2EUC( $r );
-}
-
-
-# Descriptions: get gecos field in $address.
-# return $address itself if the extraction failed.
-# Arguments: OBJ($self) STR($address)
-# Side Effects: none
-# Return Value: STR
-sub _who_of_address
-{
- my ($self, $address) = @_;
- my ($user);
-
- use Mail::Address;
- my (@addrs) = Mail::Address->parse($address);
-
- for my $addr (@addrs) {
- if (defined( $addr->phrase() )) {
- # XXX-TODO: care for non Japanese.
- my $phrase = decode_mime_string( $addr->phrase(), {
- charset => 'euc-japan',
- });
-
- if ($phrase) {
- return($phrase);
- }
- }
-
- $user = $addr->user();
- }
-
- # XXX-TODO: hmm, CROSS SITE SCRIPTING may cause ?
- if ($self->get_mode() eq 'html') {
- return( $user ? "$user\@xxx.xxx.xxx.xxx" : $address );
- }
- else {
- return $address;
- }
-}
-
-
-=head1 CODING STYLE
-
-See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-
-=head1 AUTHOR
-
-Ken'ichi Fukamachi
-
-=head1 COPYRIGHT
-
-Copyright (C) 2001,2002,2003 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::Message first appeared in fml8 mailing list driver package.
-See C<http://www.fml.org/> for more details.
-
-=cut
-
-
-1;
diff --git a/fml/lib/Mail/ThreadTrack/Print/Sort.pm b/fml/lib/Mail/ThreadTrack/Print/Sort.pm
deleted file mode 100644
index 6b0fa5bf..00000000
--- a/fml/lib/Mail/ThreadTrack/Print/Sort.pm
+++ /dev/null
@@ -1,124 +0,0 @@
-#-*- perl -*-
-#
-# Copyright (C) 2001,2002,2004 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: Sort.pm,v 1.9 2002/12/22 03:21:33 fukachan Exp $
-#
-
-package Mail::ThreadTrack::Print::Sort;
-use strict;
-use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD);
-use Carp;
-
-
-=head1 NAME
-
-Mail::ThreadTrack::Print::Sort - sort function for printing
-
-=head1 SYNOPSIS
-
-See C<Mail::ThreadTrack::Print> for usage of this subclass.
-
-=head1 DESCRIPTION
-
-See C<Mail::ThreadTrack::Print> for usage of this subclass.
-
-=head1 METHODS
-
-=head2 sort_thread_id($thread_id_list)
-
-=cut
-
-
-# Descriptions: sort ARRAY REFERENCE $thread_id_list
-# Arguments: OBJ($self) ARRAY_REF($thread_id_list)
-# Side Effects: initialize $self->{ _age } and $self->{ _cost }
-# Return Value: ARRAY_REF
-sub sort_thread_id
-{
- my ($self, $thread_id_list) = @_;
-
- # get age HASH TABLE
- my ($age, $cost) = $self->_calculate_age($thread_id_list);
- $self->{ _age } = $age;
- $self->{ _cost } = $cost;
-
- @$thread_id_list = sort {
- $cost->{$b} <=> $cost->{$a}
- } @$thread_id_list;
-
- return $thread_id_list;
-}
-
-
-my $status_cost = {
- open => ( 1 << 10 ),
- analyzed => ( 1 << 9 ),
-};
-
-
-# Descriptions: evaluate how old and status each thread is
-# Arguments: OBJ($self) ARRAY_REF($thread_id_list)
-# Side Effects: none
-# Return Value: ARRAY( HASH_REF, HASH_REF )
-sub _calculate_age
-{
- my ($self, $thread_id_list) = @_;
- my (%age, %cost) = ();
- my $now = time; # save the current UTC for convenience
- my $rh = $self->{ _hash_table } || {};
- my $day = 24*3600;
-
- # $age hash referehence = { $thread_id => $age };
- my (@aid, $last, $age, $date, $status, $tid) = ();
- for $tid (sort @$thread_id_list) {
- next unless defined $rh->{ _articles }->{ $tid };
-
- # $last: get the latest one of article_id's
- (@aid) = split(/\s+/, $rh->{ _articles }->{ $tid });
- $last = $aid[ $#aid ] || 0;
-
- # how long this thread is not concerned ?
- $age = sprintf("%2.1f%s", ($now - $rh->{ _date }->{ $last })/$day);
- $age{ $tid } = $age;
-
- # evaluate cost hash table which is { $thread_id => $cost }
- my $status = $rh->{ _status }->{ $tid };
- $cost{ $tid } = $status_cost->{ $status } + $age;
- }
-
- return (\%age, \%cost);
-}
-
-
-
-=head1 CODING STYLE
-
-See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-
-=head1 CODING STYLE
-
-See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-
-=head1 AUTHOR
-
-Ken'ichi Fukamachi
-
-=head1 COPYRIGHT
-
-Copyright (C) 2001,2002,2004 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::Sort first appeared in fml8 mailing list driver package.
-See C<http://www.fml.org/> for more details.
-
-=cut
-
-
-1;
diff --git a/fml/lib/Mail/ThreadTrack/Print/Text.pm b/fml/lib/Mail/ThreadTrack/Print/Text.pm
deleted file mode 100644
index c6d5a6a1..00000000
--- a/fml/lib/Mail/ThreadTrack/Print/Text.pm
+++ /dev/null
@@ -1,247 +0,0 @@
-#-*- perl -*-
-#
-# Copyright (C) 2001,2002,2003 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: Text.pm,v 1.14 2003/01/11 15:16:37 fukachan Exp $
-#
-
-package Mail::ThreadTrack::Print::Text;
-use strict;
-use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD);
-use Carp;
-use Mail::ThreadTrack::Print::Utils qw(decode_mime_string STR2EUC);
-
-#
-# XXX-TODO: insert more examples on format in each function.
-#
-
-=head1 NAME
-
-Mail::ThreadTrack::Print::Text - printing suitable for text
-
-=head1 SYNOPSIS
-
-See C<Mail::ThreadTrack::Print> for usage of this subclass.
-
-=head1 DESCRIPTION
-
-See C<Mail::ThreadTrack::Print> for usage of this subclass.
-
-=head1 METHODS
-
-=head2 show_articles_in_thread(thread_id)
-
-show articles as text in this thread.
-
-=cut
-
-# XXX-TODO: $is_show_cost_indicate hard-coded.
-my $is_show_cost_indicate = 0;
-
-# XXX-TODO: $format hard-coded.
-my $format = "%-20s %10s %5s %8s %s\n";
-
-
-# Descriptions: show articles as text in this thread
-# Arguments: OBJ($self) STR($thread_id)
-# Side Effects: none
-# Return Value: none
-sub show_articles_in_thread
-{
- my ($self, $thread_id) = @_;
- my $mode = $self->get_mode || 'text';
- my $config = $self->{ _config };
- my $spool_dir = $config->{ spool_dir };
- my $articles = $self->{ _hash_table }->{ _articles }->{ $thread_id };
- my $wh = $self->{ _fd } || \*STDOUT;
-
- use FileHandle;
- if (defined($articles) && defined($spool_dir) && -d $spool_dir) {
- my $s = '';
- # $articles = "1 2 3 4 5";
- for my $id (split(/\s+/, $articles)) {
- my $file = $self->filepath({
- base_dir => $spool_dir,
- id => $id,
- });
-
- my $fh = new FileHandle $file;
- if (defined $fh) {
- my $buf;
-
- LINE:
- while (defined($buf = $fh->getline())) {
- next LINE if 1 .. $buf =~ /^$/o;
-
- # XXX-TODO: we suppose Japanese only here.
- $s = STR2EUC($buf);
- print $wh $s;
- }
- $fh->close;
- }
- }
- }
-}
-
-
-# Descriptions: show guide line
-# Arguments: OBJ($self) HASH_REF($args)
-# Side Effects: none
-# Return Value: none
-sub __start_thread_summary
-{
- my ($self, $args) = @_;
- my $fd = $self->{ _fd } || \*STDOUT;
-
- # XXX-TODO: guide line is hard-coded. o.k.?
- printf($fd $format, 'id', 'date', 'age', 'status', 'articles');
- print $fd "-" x60;
- print $fd "\n";
-}
-
-
-# Descriptions: print formatted brief summary
-# Arguments: OBJ($self) HASH_REF($optargs)
-# Side Effects: none
-# Return Value: none
-sub __print_thread_summary
-{
- my ($self, $optargs) = @_;
- my $fd = $self->{ _fd } || \*STDOUT;
- my $date = $optargs->{ date };
- my $age = $optargs->{ age };
- my $status = $optargs->{ status };
- my $thread_id = $optargs->{ thread_id };
- my $articles = $optargs->{ articles };
- my $aid = (split(/\s+/, $articles))[0]; # the head of this thread
-
- printf($fd $format, $thread_id, $date, $age, $status,
- _format_list(25, $articles));
-}
-
-
-# Descriptions: print closing string, empty now (dummy).
-# Arguments: OBJ($self) HASH_REF($args)
-# Side Effects: none
-# Return Value: none
-sub __end_thread_summary
-{
- my ($self, $args) = @_;
- my $fd = $self->{ _fd } || \*STDOUT;
-}
-
-
-# Descriptions: create a string of "a b c .." style up to $num bytes
-# Arguments: NUM($max) STR($str)
-# Side Effects: none
-# Return Value: STR
-sub _format_list
-{
- my ($max, $str) = @_;
- my (@idlist) = split(/\s+/, $str);
- my $r = '';
-
- ID:
- for my $id (@idlist) {
- $r .= $id . " ";
- if (length($r) > $max) {
- $r .= "...";
- last ID;
- }
- }
-
- return $r;
-}
-
-
-# Descriptions: print message summary
-# Arguments: OBJ($self) STR($thread_id)
-# Side Effects: none
-# Return Value: none
-sub __print_message_summary
-{
- my ($self, $thread_id) = @_;
- my $config = $self->{ _config };
- my $age = $self->{ _age } || {};
- my $cost = $self->{ _cost } || {};
- my $fd = $self->{ _fd } || \*STDOUT;
- my $rh = $self->{ _hash_table };
-
- if (defined $config->{ spool_dir }) {
- my ($aid, @aid, $file);
- my $spool_dir = $config->{ spool_dir };
-
- THREAD_ID_LIST:
- for my $thread_id (@$thread_id) {
- if ($is_show_cost_indicate) {
- my $how_bad = _cost_to_indicator( $cost->{ $thread_id } );
- printf $fd "\n%6s %-10s %s\n", $how_bad, $thread_id;
- }
- else {
- printf $fd "\n>Thread-Id: %-10s %s\n", $thread_id;
- }
-
- # show only the first article of this thread $thread_id
- if (defined $rh->{ _articles }->{ $thread_id }) {
- (@aid) = split(/\s+/, $rh->{ _articles }->{ $thread_id });
- $aid = $aid[0];
- $file = $self->filepath({
- base_dir => $spool_dir,
- id => $aid,
- });
- if (-f $file) {
- $self->print( $self->message_summary($file) );
- }
- }
- }
- }
-}
-
-
-# Descriptions: for example, cost -> '!!!'
-# broken now ;-)
-# Arguments: STR($cost)
-# Side Effects: none
-# Return Value: STR
-sub _cost_to_indicator
-{
- my ($cost) = @_;
- my $how_bad = 0;
-
- # XXX-TODO: cost indicator is broken ?
- if ($cost =~ /(\w+)\-(\d+)/) {
- $how_bad += $2;
- $how_bad += 2 if $1 =~ /open/;
- $how_bad = "!" x ($how_bad > 6 ? 6 : $how_bad);
- }
-
- $how_bad;
-}
-
-
-=head1 CODING STYLE
-
-See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-
-=head1 AUTHOR
-
-Ken'ichi Fukamachi
-
-=head1 COPYRIGHT
-
-Copyright (C) 2001,2002,2003 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::Text first appeared in fml8 mailing list driver package.
-See C<http://www.fml.org/> for more details.
-
-=cut
-
-
-1;
diff --git a/fml/lib/Mail/ThreadTrack/Print/Utils.pm b/fml/lib/Mail/ThreadTrack/Print/Utils.pm
deleted file mode 100644
index 45bfcbcf..00000000
--- a/fml/lib/Mail/ThreadTrack/Print/Utils.pm
+++ /dev/null
@@ -1,115 +0,0 @@
-#-*- perl -*-
-#
-# Copyright (C) 2001,2002,2004 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: Utils.pm,v 1.6 2002/12/22 03:21:33 fukachan Exp $
-#
-
-package Mail::ThreadTrack::Print::Utils;
-use strict;
-use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD);
-use Carp;
-
-require Exporter;
-@ISA = qw(Exporter);
-@EXPORT_OK = qw(decode_mime_string STR2EUC);
-
-
-=head1 NAME
-
-Mail::ThreadTrack::Print::Utils - utility functions
-
-=head1 SYNOPSIS
-
- use Mail::ThreadTrack::Print::Utils qw(decode_mime_string STR2EUC);
-
-=head1 DESCRIPTION
-
-utility functions to manipulate Japanese string.
-
-=head1 METHODS
-
-=head2 decode_mime_string(string, [$options])
-
-decode a base64/quoted-printable encoded string to a plain message.
-The encoding method is automatically detected.
-
-C<$options> is a HASH REFERENCE.
-You can specify the charset of the string to return
-by $options->{ charset }.
-
-=head2 STR2EUC(str)
-
-convert str to Japanese EUC.
-
-=cut
-
-
-# Descriptions: decode $str
-# Arguments: STR($str) HASH_REF($options)
-# Side Effects: none
-# Return Value: STR
-sub decode_mime_string
-{
- my ($str, $options) = @_;
- my $charset = $options->{ 'charset' } || 'euc-japan';
-
- # XXX-TODO: care for non Japanese.
- if ($charset eq 'euc-japan') {
- if ($str =~ /=\?ISO\-2022\-JP\?B\?(\S+\=*)\?=/i) {
- eval q{ use MIME::Base64; };
- $str =~ s/=\?ISO\-2022\-JP\?B\?(\S+\=*)\?=/decode_base64($1)/gie;
- }
-
- if ($str =~ /=\?ISO\-2022\-JP\?Q\?(\S+\=*)\?=/i) {
- eval q{ use MIME::QuotedPrint;};
- $str =~ s/=\?ISO\-2022\-JP\?Q\?(\S+\=*)\?=/decode_qp($1)/gie;
- }
- }
-
- use Jcode;
- &Jcode::convert(\$str, 'euc');
- $str;
-}
-
-
-# Descriptions: convert $str to Japanese EUC
-# Arguments: STR($str)
-# Side Effects: none
-# Return Value: STR
-sub STR2EUC
-{
- my ($str) = @_;
-
- use Jcode;
- &Jcode::convert(\$str, 'euc');
- return $str;
-}
-
-
-=head1 CODING STYLE
-
-See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-
-=head1 AUTHOR
-
-Ken'ichi Fukamachi
-
-=head1 COPYRIGHT
-
-Copyright (C) 2001,2002,2004 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::Utils first appeared in fml8 mailing list driver package.
-See C<http://www.fml.org/> for more details.
-
-=cut
-
-
-1;