summaryrefslogtreecommitdiffstats
path: root/bin/update_addressbook
blob: 5fc0db4f7ea71abbb17cab9414fbbce8aa5324ad (plain) (blame)
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
81
82
83
84
85
86
87
#!/usr/bin/env perl
use strict;
use warnings;
use 5.014;

use Email::Address;
use List::MoreUtils 'any';
use Path::Class;
use Text::CSV;

sub existing_addresses {
    my ($addressbook) = @_;

    open my $fh, '-|', (
        'abook',
        '--convert',
        '--infile', $addressbook,
        '--outformat', 'csv'
    ) or die "Couldn't run abook: $!";

    my $csv = Text::CSV->new;
    my @out;
    while (my $row = $csv->getline($fh)) {
        push @out, Email::Address->new($row->[0], $row->[1]);
    }

    $fh->close;

    return @out;
}

my @exclude_patterns = (
    qr/^"?=\?/, # quoted-printable encoded addresses - punt for now
    qr/<notifications\@github\.com>/,
    qr/\@(?:.*\.)?stripe\.io\b/,
    qr/(?:no|do-?not)-?reply/i,
    qr/via (.*)"? <\1\@/,
    qr/support\@stripe\.com/,
);

sub maildir_senders {
    my ($maildir) = @_;

    my $all_mail = dir($maildir)->subdir('[Gmail].All Mail')->subdir('cur');
    my %senders;
    for my $file ($all_mail->children) {
        my $fh = $file->openr;
        while (<$fh>) {
            last if /^$/;
            next unless /^(?:From|Sender): /;
            my @addresses = Email::Address->parse($_);
            $senders{$_->format} = $_ for @addresses;
        }
        $fh->close;
    }

    return grep {
        my $address = $_->format;
        !any { $address =~ $_ } @exclude_patterns
    } values %senders;
}

{
    my $addressbook       = "$ENV{HOME}/.abook/addressbook";
    my $maildir           = "$ENV{HOME}/Maildir";

    my @addresses = (
        existing_addresses($addressbook),
        maildir_senders($maildir),
        # ... (hardcoded things?)
    );
    my %addresses = map { $_->address => $_ } @addresses;
    @addresses = sort values %addresses;

    file($addressbook)->move_to("$addressbook.bak");

    open my $fh, '|-', (
        'abook',
        '--convert',
        '--informat', 'csv',
        '--outformat', 'abook',
        '--outfile', $addressbook,
    ) or die "Couldn't run abook: $!";
    for my $address (@addresses) {
        $fh->print(qq{"@{[$address->phrase || $address->address]}","@{[$address->address]}","","",""\n});
    }
}