aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authordakkar <dakkar@thenautilus.net>2017-02-07 19:44:20 +0000
committerdakkar <dakkar@thenautilus.net>2017-02-07 19:44:20 +0000
commit16d3d040fa37a5161811367174ef32b19aee01dd (patch)
tree8639615e9fd34af9ee10f8ac7ad44fdf5b3325ba /lib
parentfix POD typos (diff)
downloadSietima-16d3d040fa37a5161811367174ef32b19aee01dd.tar.gz
Sietima-16d3d040fa37a5161811367174ef32b19aee01dd.tar.bz2
Sietima-16d3d040fa37a5161811367174ef32b19aee01dd.zip
POD for ::MailStore::FS
Diffstat (limited to 'lib')
-rw-r--r--lib/Sietima/MailStore/FS.pm114
1 files changed, 110 insertions, 4 deletions
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<Sietima::MailStore> >> interface,
+storing emails as files on disk.
+
+=cut
+
with 'Sietima::MailStore';
+=attr C<root>
+
+Required, a L<< C<Path::Tiny> >> 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<Sietima::Role::SubscriberOnly::Moderate> >>). 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<store>
+
+ my $id = $store->store($email_mime_object,@tags);
+
+Stores the given email message inside the L<store root|/root>, 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<retrieve_by_id>
+
+ my $email_mime_object = $store->retrieve_by_id($id);
+
+Given an identifier returned by L<< /C<store> >>, this method returns
+the email message.
+
+If the message has been deleted, or the identifier is not recognised,
+this method returns C<undef> 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<retrieve_ids_by_tags>
+
+ 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<retrieve_by_tags>
+
+ my @email_mime_objects = $store->retrieve_by_tags(@tags)->@*;
+
+This method is similar to L<< /C<retrieve_ids_by_tags> >>, 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<remove>
+
+ $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<clear>
+
+ $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;