]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blob - IkiWiki/Plugin/mailbox.pm
initial MIME handling
[git.ikiwiki.info.git] / IkiWiki / Plugin / mailbox.pm
1 #!/usr/bin/perl
2 # based on Ikiwiki skeleton plugin.
4 # Copyright (c) 2008 David Bremner <bremner@unb.ca>
5 # This file is distributed under the Artistic License/GPL2+
7 use Email::MIME;
8 package Email::MIMEFolder;
9 use base 'Email::Folder';
10 sub bless_message { return  Email::MIME->new($_[1]) };
12 package IkiWiki::Plugin::mailbox;
14 use IkiWiki 2.00;
15 use Email::Folder;
16 use Email::Thread;
17 use CGI 'escapeHTML';
18 use Data::Dumper;
20 my %metaheaders;
22 sub import { #{{{
23         hook(type => "preprocess", id => "mailbox", call => \&preprocess);
24         hook(type => "scan", id => "mailbox", call => \&scan);
25         hook(type => "pagetemplate", id=>"mailbox", call => \&pagetemplate);
26 } # }}}
28 sub scan(@){
29         my %params=@_;
30         my $page=$params{page};
32         push @{$metaheaders{$page}}, 
33                '<link rel="stylesheet" href="mailbox.css" type="text/css"/>'
34 }
36 sub preprocess (@) { #{{{
37         my %params=@_;
38         
39         my $page=$params{page};
40         my $type=$params{type} || 'maildir';
42         my $path=$params{path} ||  error gettext("missing parameter") . " path";
43         
44         # hmm, this should probably only be inserted once per page.
46         # note, mbox is not a directory, needs to be special cased
47         my $dir=bestdir($page,$params{path}) || 
48             error("could not find ".$params{path});
50         $params{path} = $config{srcdir} ."/" . $dir;
52         return  format_mailbox(path=>$dir,%params);
54 } # }}}
57 ### The guts of the plugin
58 ### parameters 
59 sub format_mailbox(@){
60     my %params=@_;
61     my $path=$params{path} || error("path parameter mandatory");
63     my $folder=Email::MIMEFolder->new($path) || error("mailbox could not be opened");
64     my $threader=new Email::Thread($folder->messages);
66     $threader->thread();
68     return join "\n", map { format_thread(thread=>$_) } $threader->rootset;
69 }
71 sub format_thread(@){
72     my %params=@_;
73     
74     my $thread=$params{thread} || error gettext("missing parameter") . "thread";
76     my $output="";
78     if ($thread->message) {
79         $output .= format_message(message=>$thread->message);
80     } else {
81         $output .= sprintf gettext("Message %s not available"), $thread;
82     }
84     if ($thread->child){
85         $output .= '<div class="emailthreadindent">' .
86             format_thread(thread=>$thread->child).
87             '</div>';
88     }
90     if ($thread->next){
91         $output .= format_thread(thread=>$thread->next);
92     }
93     return $output;
94 }
96 sub make_pair($$){
97     my $message=shift;
98     my $name=shift;
99     my $val=$message->header($_);
100     
101     $val = escapeHTML($val);
103     my $hash={'HEADERNAME'=>$name,'VAL'=>$val};
104     return $hash;
106 sub format_message(@){
107     my  %params=@_;
109     my $message=$params{message} || 
110         error gettext("missing parameter"). "message";
112     my $keep_headers=$params{headers} || qr/^(subject|from|date)/i;
113     
114     my $template= 
115         template("email.tmpl") || error gettext("missing template");
117     my $output="";
119     my @names = grep  {m/$keep_headers/;}  ($message->header_names);
120     my @headers=map { make_pair($message,$_) } @names;
121     
123     $template->param(HEADERS=>[@headers]);
126     my $body= join("\n", map { $_->body }  $message->parts);
128     $template->param(body=>format_body($body));
130     $output .= $template->output();
131     return $output;
134 sub format_body($){
135     my $body=shift;
137     # it is not completely clear to me the right way to go here.  
138     # passing things straight to markdown is not working all that
139     # well.
140     return "<pre>".escapeHTML($body)."</pre>";
142 ### Utilities
144 # From Arpit Jain
145 # http://ikiwiki.info/todo/Bestdir_along_with_bestlink_in_IkiWiki.pm/
146 # need to clarify license
147 sub bestdir ($$) { #{{{
148     my $page=shift;
149        my $link=shift;
150        my $cwd=$page;
152        if ($link=~s/^\/+//) {
153                $cwd="";
154        }
156        do {
157                my $l=$cwd;
158                $l.="/" if length $l;
159                $l.=$link;
160                if (-d "$config{srcdir}/$l") {
161                        return $l;
162                }
163        } while $cwd=~s!/?[^/]+$!!;
165        if (length $config{userdir}) {
166                my $l = "$config{userdir}/".lc($link);
168                if (-d $l) {
169                        return $l;
170                }
171        }
173        return "";
174 } #}}}
176 sub pagetemplate (@) { #{{{
177         my %params=@_;
178         my $page=$params{page};
179         my $destpage=$params{destpage};
180         my $template=$params{template};
182         if (exists $metaheaders{$page} && $template->query(name => "meta")) {
183                 # avoid duplicate meta lines
184                 my %seen;
185                 $template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$metaheaders{$page}}));
186         }
191 1;