summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordakkar <dakkar@thenautilus.net>2018-11-09 15:19:16 +0000
committerdakkar <dakkar@thenautilus.net>2018-11-09 15:19:16 +0000
commit3b97aa0df99bcad2656899c03ee1f759cb3efc55 (patch)
tree96fbf7a5d09dfa58b1e0d2341ed2585792035a33
parentignore precompiled directory (diff)
downloadMaildirIndexer-3b97aa0df99bcad2656899c03ee1f759cb3efc55.tar.gz
MaildirIndexer-3b97aa0df99bcad2656899c03ee1f759cb3efc55.tar.bz2
MaildirIndexer-3b97aa0df99bcad2656899c03ee1f759cb3efc55.zip
in-memory store, and Email class
-rw-r--r--bayes18
-rw-r--r--lib/MaildirIndexer/Email.pm621
-rw-r--r--lib/MaildirIndexer/Parser.pm68
-rw-r--r--lib/MaildirIndexer/Store.pm643
4 files changed, 84 insertions, 6 deletions
diff --git a/bayes b/bayes
index c7c81bf..0843976 100644
--- a/bayes
+++ b/bayes
@@ -2,21 +2,31 @@
use v6.d.PREVIEW;
use lib 'lib';
use MaildirIndexer::ScanDir;
-use MaildirIndexer::Parser;
+use MaildirIndexer::Store;
sub MAIN($maildir) {
+ my $store = MaildirIndexer::Store.new;
+
my $file-supply = scan-dir($maildir);
my $file-channel = $file-supply.Channel;
+
for ^10 {
start react {
whenever $file-channel -> $file {
if $file.e && $file.f {
- my $email = parse-email($file,:headers-only);
- say "{$file} - {$email<headers><Subject>}";
+ $store.add-file($file);
+ }
+ elsif !$file.e {
+ $store.del-file($file);
}
}
}
}
- react whenever signal(SIGINT) { exit }
+ react {
+ whenever signal(SIGINT) { exit }
+ whenever signal(SIGHUP) {
+ $store.dump();
+ }
+ }
}
diff --git a/lib/MaildirIndexer/Email.pm6 b/lib/MaildirIndexer/Email.pm6
new file mode 100644
index 0000000..f5d1c39
--- /dev/null
+++ b/lib/MaildirIndexer/Email.pm6
@@ -0,0 +1,21 @@
+use v6.d.PREVIEW;
+unit class MaildirIndexer::Email;
+
+has %!headers;
+has $!body;
+
+method BUILD(:%!headers,:$!body) { }
+
+method message-id { split-refs(%!headers<message-id>)[0] }
+method refs {
+ return |(
+ split-refs(%!headers<in-reply-to>),
+ split-refs(%!headers<references>).reverse,
+ );
+}
+
+multi split-refs(Any) { return (); }
+multi split-refs(Str:D $str) {
+ return $/<refs>».Str if $str ~~ m{'<' $<refs> = (<-[<>]>+)+ % [ '>' .*? '<' ] '>' };
+ return ();
+}
diff --git a/lib/MaildirIndexer/Parser.pm6 b/lib/MaildirIndexer/Parser.pm6
index 90b3678..c2425fe 100644
--- a/lib/MaildirIndexer/Parser.pm6
+++ b/lib/MaildirIndexer/Parser.pm6
@@ -1,5 +1,6 @@
use v6.d.PREVIEW;
unit module MaildirIndexer::Parser;
+use MaildirIndexer::Email;
my @separators = (
"\x0a\x0d\x0a\x0d",
@@ -38,13 +39,16 @@ grammar Message {
class Message-actions {
method TOP($/) {
- make %( headers => $/<headers>.made, body => $/<body>.Str );
+ make MaildirIndexer::Email.new(
+ headers => $/<headers>.made,
+ body => $/<body>.Str,
+ );
}
method headers($/) {
make %( |$/<header>».made );
}
method header($/) {
- make $/<junk> ?? () !! ( $/<name>.Str => $/<value>.made );
+ make $/<junk> ?? () !! ( $/<name>.Str.lc => $/<value>.made );
}
method value($/) {
make $/<line>.join(' ')
diff --git a/lib/MaildirIndexer/Store.pm6 b/lib/MaildirIndexer/Store.pm6
new file mode 100644
index 0000000..cbfcfa1
--- /dev/null
+++ b/lib/MaildirIndexer/Store.pm6
@@ -0,0 +1,43 @@
+use v6.d.PREVIEW;
+unit class MaildirIndexer::Store;
+use MaildirIndexer::Parser;
+
+has %!id-for-file;
+has %!mailboxes-for-id;
+has $!lock = Lock.new;
+
+method dump() {
+ $!lock.protect: {
+ say "{.key} → {.value}" for %!id-for-file;
+ say "{.key} ⇒ {.value.perl}" for %!mailboxes-for-id;
+ }
+}
+
+method add-file(IO $file) {
+ my $email = parse-email($file,:headers-only);
+ my $id = $email.message-id or return;
+ my $mailbox = mailbox-from-path($file.path) or return;
+ $!lock.protect: {
+ %!id-for-file{ $file.path } = $id;
+ %!mailboxes-for-id{ $id }.push($mailbox);
+ };
+ return;
+}
+
+method del-file(IO $file) {
+ my $mailbox = mailbox-from-path($file.path) or return;
+ $!lock.protect: {
+ my $id = %!id-for-file{ $file.path }:delete;
+ with %!mailboxes-for-id{ $id } {
+with .grep($mailbox):k -> $pos {
+ .splice($pos,1);
+ }
+}
+ }
+ return;
+}
+
+sub mailbox-from-path(Str() $path) {
+ $path ~~ m{'/' (<-[/]>+?) '/' [cur|new|tmp] '/'} and return ~$/[0];
+ return Nil;
+}