summaryrefslogtreecommitdiff
path: root/lib/MaildirIndexer/Store.rakumod
blob: 856bacac45bc99ef0ad98ec11ce448979ea6e149 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use v6.d;
unit class MaildirIndexer::Store;
use MaildirIndexer::LogTimelineSchema;
use MaildirIndexer::Index;
use MaildirIndexer::Parser;
use MaildirIndexer::ScanDir;
 
has Lock $!lock .= new;
has MaildirIndexer::Index @.indices is required;
has Channel $.file-channel is required;
has Int $.workers = Kernel.cpu-cores - 1;
has Channel @!index-channels = Channel.new xx +@!indices;
 
method dump(--> Nil{
    $!lock.protect: {
        .dump() for @!indices;
    }
}
 
method start(--> Nil{
    for @.indices Z @!index-channels -> ($i, $c{
        start $i.receive($c);
    }
 
    for ^$.workers {
        start react {
            whenever $.file-channel -> $file {
                CATCH { warn "looking at $file\n"warn .gist };
                when $file ~~ MaildirIndexer::ScanDir::End {
                    MaildirIndexer::LogTimelineSchema::Scan::End.log();
                }
                when $file ~~ :e & :f {
                    MaildirIndexer::LogTimelineSchema::Store::Add.log: :file($file.path), -> {
                        self.add-file($file);
                    }
                }
                when $file ~~ :!e {
                    MaildirIndexer::LogTimelineSchema::Store::Rm.log: :file($file.path), -> {
                        self.del-file($file);
                    }
                }
            }
        }
    }
}
 
method add-file(IO:D $file --> Nil{
    my Str $mailbox = mailbox-from-path($file.pathor return;
    my MaildirIndexer::Email $email = parse-email($file,:headers-onlyor return;
    my $event = AddMail.new(:$email,:$mailbox);
    .send($eventfor @!index-channels;
 
    return;
}
 
method del-file(IO:D $file --> Nil{
    my $mailbox = mailbox-from-path($file.pathor return;
 
    my $event = DelPath.new(:path($file),:$mailbox);
    .send($eventfor @!index-channels;
 
    return;
}
 
method mailbox-for-email(MaildirIndexer::Email:D $email --> Str{
    my Str $result;
    my Channel $replies .= new;
    my $event = MailboxForEmail.new(:$email,:reply-to($replies));
    MaildirIndexer::LogTimelineSchema::Store::Find.log: {
        .send($eventfor @!index-channels;
        my @results = $replies.receive() xx @!index-channels;
        $result = @results.grep(*.defined).join("\n");
    }
    return $result;
}
 
sub mailbox-from-path(Str() $path --> Str{
    $path ~~ m{'/' (<-[/]>+?'/' [cur|new|tmp] '/'} and return ~$/[0];
    return Nil;
}