From 16d3d040fa37a5161811367174ef32b19aee01dd Mon Sep 17 00:00:00 2001 From: dakkar Date: Tue, 7 Feb 2017 19:44:20 +0000 Subject: POD for ::MailStore::FS --- lib/Sietima/MailStore/FS.pm | 114 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 4 deletions(-) (limited to 'lib/Sietima') diff --git a/lib/Sietima/MailStore/FS.pm b/lib/Sietima/MailStore/FS.pm index adc1c03..d34b388 100644 --- a/lib/Sietima/MailStore/FS.pm +++ b/lib/Sietima/MailStore/FS.pm @@ -11,8 +11,38 @@ use namespace::clean; # VERSION # ABSTRACT: filesystem-backed email store +=head1 SYNOPSIS + + my $store = Sietima::MailStore::FS->new({ root => '/tmp/my-store' }); + +=head1 DESCRIPTION + +This class implements the L<< C >> interface, +storing emails as files on disk. + +=cut + with 'Sietima::MailStore'; +=attr C + +Required, a L<< C >> object that points to an existing +directory. Coercible from a string. + +It's a good idea for the directory to be readable and writable by the +user who will run the mailing list, and also by all users who will run +administrative commands (like those provided by L<< +C >>). A way to achieve that +is to have a group dedicated to list owners, and set the directory +group-writable and group-sticky, and owned by that group: + + # chgrp-R mailinglists /tmp/my-store + # chmod -R g+rwXs /tmp/my-store + +=for Pod::Coverage BUILD + +=cut + has root => ( is => 'ro', required => 1, @@ -29,10 +59,18 @@ sub BUILD($self,@) { return; } -sub clear($self) { - do { $self->$_->remove_tree;$self->$_->mkpath } for qw(_tagdir _msgdir); - return; -} +=head2 C + + my $id = $store->store($email_mime_object,@tags); + +Stores the given email message inside the L, and +associates with the given tags. + +Returns a unique identifier for the stored message. If you store twice +the same message (or two messages that stringify identically), you'll +get the same identifier. + +=cut sub store($self,$mail,@tags) { state $check = compile(Object,EmailMIME,slurpy ArrayRef[TagName]);$check->(@_); @@ -47,6 +85,19 @@ sub store($self,$mail,@tags) { return $id; } +=head2 C + + my $email_mime_object = $store->retrieve_by_id($id); + +Given an identifier returned by L<< /C >>, this method returns +the email message. + +If the message has been deleted, or the identifier is not recognised, +this method returns C in scalar context, or an empty list in +list context. + +=cut + sub retrieve_by_id($self,$id) { state $check = compile(Object,Str);$check->(@_); @@ -55,6 +106,20 @@ sub retrieve_by_id($self,$id) { return Email::MIME->new($msg_path->slurp_raw); } +=head2 C + + my @ids = $store->retrieve_ids_by_tags(@tags)->@*; + +Given a list of tags, this method returns an arrayref containing the +identifiers of all (and only) the messages that were stored associated +with (at least) all those tags. The order of the returned identifiers +is essentially random. + +If there are no messages associated with the given tags, this method +returns an empty arrayref. + +=cut + sub _tagged_by($self,$tag) { my $tag_file = $self->_tagdir->child($tag); return unless -e $tag_file; @@ -64,6 +129,7 @@ sub _tagged_by($self,$tag) { sub retrieve_ids_by_tags($self,@tags) { state $check = compile(Object,slurpy ArrayRef[TagName]);$check->(@_); + # this maps: id -> how many of the given @tags it has my %msgs; if (@tags) { for my $tag (@tags) { @@ -76,12 +142,28 @@ sub retrieve_ids_by_tags($self,@tags) { my @ret; for my $id (keys %msgs) { + # if this message id does not have all the required tags, we + # won't return it next unless $msgs{$id} == @tags; push @ret, $id; } return \@ret; } +=head2 C + + my @email_mime_objects = $store->retrieve_by_tags(@tags)->@*; + +This method is similar to L<< /C >>, but it +returns an arrayref of hashrefs like: + + $store->retrieve_ids_by_tags('t1') ==> [ + { id => $id1, mail => $msg1 }, + { id => $id2, mail => $msg2 }, + ] + +=cut + sub retrieve_by_tags($self,@tags) { state $check = compile(Object,slurpy ArrayRef[TagName]);$check->(@_); @@ -96,6 +178,15 @@ sub retrieve_by_tags($self,@tags) { return \@ret; } +=head2 C + + $store->remove($id); + +This method removes the message corresponding to the given identifier +from disk. Removing a non-existent message does nothing. + +=cut + sub remove($self,$id) { state $check = compile(Object,Str);$check->(@_); @@ -107,4 +198,19 @@ sub remove($self,$id) { return; } +=method C + + $store->clear(); + +This method removes all messages from disk. Clearing as empty store +does nothing. + + +=cut + +sub clear($self) { + do { $self->$_->remove_tree;$self->$_->mkpath } for qw(_tagdir _msgdir); + return; +} + 1; -- cgit v1.2.3