File Coverage

blib/lib/GraphViz/Mail.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package GraphViz::Mail;
2              
3 1     1   822 use strict;
  1         2  
  1         42  
4 1     1   6823 use Mail::Thread;
  1         59672  
  1         37  
5 1     1   468 use GraphViz;
  0            
  0            
6             use Date::Parse qw( str2time );
7             use base qw( Class::Accessor::Chained::Fast );
8             __PACKAGE__->mk_accessors(qw( messages width height graph thread));
9              
10             use vars qw($VERSION);
11              
12              
13             $VERSION = "0.1";
14              
15              
16              
17             =head1 NAME
18              
19             GraphViz::Mail - visualise a Mail thread as a tree
20              
21             =head1 SYNOPSIS
22              
23             my $threader = Mail::Thread->new( @messages );
24             $threader->thread;
25              
26             my $i;
27             for my $thread ($threader->rootset) {
28             ++$i;
29             my $gm = GraphViz::Mail->new($thread);
30             write_file( "thread_$i.svg", $gm->as_png );
31             }
32              
33             =head1 DESCRIPTION
34              
35             GraphViz::Mail takes a Mail::Thread::Container and generates a
36             graph of the thread.
37              
38             =head1 METHODS
39              
40             =head2 new
41              
42             Generic constructor, takes a Mail::Thread::Container
43              
44             =cut
45              
46             sub new {
47             my $proto = shift;
48             my $class = ref($proto) || $proto;
49             my $thread = shift;
50              
51             my $graph = GraphViz->new();
52            
53             my $self = {};
54             bless $self, ref $class || $class;
55             $self->graph($graph);
56             $self->thread($thread);
57             $self->_init();
58              
59             return $graph;
60             }
61              
62             =head2 as_*
63              
64             The Thread can be visualised in a number of different graphical
65             formats. Methods include as_ps, as_hpgl, as_pcl, as_mif, as_pic,
66             as_gd, as_gd2, as_gif, as_jpeg, as_png, as_wbmp, as_ismap, as_imap,
67             as_vrml, as_vtx, as_mp, as_fig, as_svg. See the GraphViz documentation
68             for more information. The two most common methods are:
69              
70             # Print out a PNG-format file
71             print $g->as_png;
72              
73             # Print out a PostScript-format file
74             print $g->as_ps;
75              
76             =cut
77              
78             sub _init {
79             my $self = shift;
80              
81             my $g = $self->graph();
82             my $root = $self->thread();
83              
84              
85             # extract just the containers with messages
86             my @messages;
87             $root->iterate_down(
88             sub {
89             my $container = shift;
90             push @messages, $container; # if $container->message;
91             } );
92              
93             # sort on date
94             @messages = sort {
95             $self->date_of( $a ) <=> $self->date_of( $b )
96             } @messages;
97              
98              
99             {
100             # assign the numbers needed to compute X
101             my $i;
102             $self->messages( { map { $_ => ++$i } @messages } );
103             }
104             $self->draw_arc( $_->parent, $_ ) for @messages;
105             $self->draw_message( $_ ) for @messages;
106              
107              
108             }
109              
110             =head2 draw_message( $message )
111              
112             Draw the message on the Graph.
113              
114             =cut
115              
116             sub draw_message {
117             my ($self, $message) = @_;
118            
119             my $colour = 'red';
120             my $shape = 'ellipse';
121             my $from = $message->header('from');
122             my $subj = $message->header('subject');
123              
124             $self->graph()->add_node($message, label => "$from:\n $subj" , color => $colour, shape => $shape);
125              
126             }
127              
128             =head2 draw_arc( $from, $to )
129              
130             draws an arc between two messages
131              
132             =cut
133              
134             sub draw_arc {
135             my ($self, $from, $to) = @_;
136             $self->graph()->add_edge($from => $to);
137              
138             }
139              
140             =head2 date_of( $container )
141              
142             The date the message was sent, in epoch seconds
143              
144             =cut
145              
146             sub date_of {
147             my ($self, $container) = @_;
148             return str2time $container->header( 'date' );
149             }
150              
151              
152              
153              
154              
155             =head1 BUGS
156              
157             None known.
158              
159             =head1 AUTHOR
160              
161             Simon Wistow EFE
162              
163             =head1 COPYRIGHT
164              
165             Copyright (C) 2003, Simon Wistow
166              
167             This module is free software; you can redistribute it or modify it
168             under the same terms as Perl itself.
169              
170             =cut
171              
172             1;
173