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+
8 use Email::MIME::Modifier;
9 package Email::MIMEFolder;
10 use base 'Email::Folder';
11 sub bless_message { return Email::MIME->new($_[1]) };
14 package IkiWiki::Plugin::mailbox;
16 use Email::FolderType qw(folder_type);
20 use File::Temp qw/tempfile/;
21 use File::MimeInfo::Magic;
28 hook(type => "preprocess", id => "mailbox", call => \&preprocess);
29 hook(type => "scan", id => "mailbox", call => \&scan);
30 hook(type => "pagetemplate", id=>"mailbox", call => \&pagetemplate);
31 hook(type => "htmlize",id=>"mbox",call => \&mbox_htmlize);
32 IkiWiki::loadplugin("filecheck");
37 my $page=$params{page};
39 push @{$metaheaders{$page}},
40 '<link rel="stylesheet" href="mailbox.css" type="text/css"/>'
43 sub preprocess (@) { #{{{
46 my $page=$params{page};
47 my $type=$params{type} || 'Maildir';
49 my $path=$params{path} || error gettext("missing parameter") . " path";
51 # hmm, this should probably only be inserted once per page.
53 my $dir=bestpath($page,$params{path}) ||
54 error("could not find ".$params{path});
56 $params{path} = $config{srcdir} ."/" . $dir;
57 $params{type} = $type;
59 return format_mailbox(%params);
64 ### The guts of the plugin
66 sub format_mailbox(@){
68 my $path=$params{path} || error gettext("missing parameter "). 'path';
69 my $type=$params{type} || error gettext("missing paramater ")."type";
72 my $folder=Email::MIMEFolder->new($path,reader=>'Email::Folder::'.$type) || error("mailbox could not be opened");
73 my $threader=new Email::Thread($folder->messages);
77 return join "\n", map { format_thread(%params,thread=>$_) } $threader->rootset;
83 my $thread=$params{thread} || error gettext("missing parameter") . "thread";
87 if ($thread->message) {
88 $output .= format_message(%params,message=>$thread->message);
90 $output .= sprintf gettext("Message %s not available"), $thread->messageid;
94 $output .= '<div class="emailthreadindent">' .
95 format_thread(%params,thread=>$thread->child).
100 $output .= format_thread(%params,thread=>$thread->next);
108 my $val=$message->header($_);
110 $val = escapeHTML($val);
112 my $hash={'HEADERNAME'=>$name,'VAL'=>$val};
115 sub format_message(@){
118 my $message=$params{message} ||
119 error gettext("missing parameter"). "message";
122 my $dest=$params{destpage} ||
123 error gettext("missing parameter"). "destpage";
125 my $keep_headers=$params{headers} || qr/^(subject|from|date)[:]?$/i;
128 template("email.tmpl") || error gettext("missing template");
132 my @names = grep {m/$keep_headers/;} ($message->header_names);
133 my @headers=map { make_pair($message,$_) } @names;
136 $template->param(HEADERS=>[@headers]);
138 my $allowed_attachments=$params{allowed_attachments} ||
139 "maxsize(100kb) and mimetype(text/plain)";
141 my @parts=$message->parts;
145 #this sucks. But someone would need to modify filecheck to
146 #accept a blob of content. Or maybe hacking with IO::Scalar
147 my $tmpfile=File::Temp->new();
149 binmode $tmpfile,':utf8';
150 print $tmpfile $_->body();
152 my $allowed=pagespec_match($dest, $allowed_attachments, file=>$tmpfile);
155 debug("clobbering attachment $partcount");
156 $_->content_type_set('text/plain');
157 $_->body_set("[ omitting part $partcount: $allowed ]");
162 my $body= join("\n", map { $_->body } @parts);
164 $template->param(body=>format_body($body));
166 $output .= $template->output();
173 # it is not completely clear to me the right way to go here.
174 # passing things straight to markdown is not working all that
176 return "<pre>".escapeHTML($body)."</pre>";
180 # based on bestdir From Arpit Jain
181 # http://ikiwiki.info/todo/Bestdir_along_with_bestlink_in_IkiWiki.pm/
182 # need to clarify license
183 sub bestpath ($$) { #{{{
188 if ($link=~s/^\/+//) {
194 $l.="/" if length $l;
196 if (-d "$config{srcdir}/$l" || -f "$config{srcdir}/$l") {
199 } while $cwd=~s!/?[^/]+$!!;
201 if (length $config{userdir}) {
202 my $l = "$config{userdir}/".lc($link);
204 if (-d $l || -f $l) {
212 sub pagetemplate (@) { #{{{
214 my $page=$params{page};
215 my $destpage=$params{destpage};
216 my $template=$params{template};
218 if (exists $metaheaders{$page} && $template->query(name => "meta")) {
219 # avoid duplicate meta lines
221 $template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$metaheaders{$page}}));
227 package Email::FolderType::MH;
231 return 0 if (! -d $folder);
232 opendir DIR,$folder || error("opendir failed");
235 return 0 if (!m|\.| && !m|\.\.| && !m|\d+|);