The iPhone OS is capable of syncing "Notes" with a special folder in your mail account (usually over IMAP) such that each note is listed as a message in your mail system.
This is handy for reading/writing your Notes in mail clients on other machines/devices, but I really wanted a way to have automated tools update Notes directly. This script reads from STDIN, and takes care of the special iPhone Mail Header subtleties.
#!/usr/bin/perl
#
# run iphonenote.pl --help for usage
#
# $Id: iphonenote.pl 32 2011-02-22 04:26:00Z hossman $
#
use strict;
use warnings;
use Getopt::Long;
use Pod::Usage;
use Data::UUID;
use Mail::Message;
use Mail::Box::Manager;
use constant SUBJ_HEADER => 'Subject';
use constant UUID_HEADER => 'X-Universally-Unique-Identifier';
use constant TYPE_HEADER => 'X-Uniform-Type-Identifier';
use constant TYPE_VALUE => 'com.apple.mail-note';
my %folder_opts = ('access'=>'rw');
my $foldername = undef;
my $uuid = undef;
my $help = 0;
my $gmail = 0;
my $create = 0;
my $modify = 0;
my $delete = 0;
GetOptions('help|usage|?' => \$help,
'folder|f=s' => \$foldername,
'opt|opts=s%' => \%folder_opts,
'uuid|u=s' => \$uuid,
'create|c' => \$create,
'modify|m' => \$modify,
'delete|d' => \$delete,
'gmail|g' => \$gmail,
) or pod2usage(2);
pod2usage(1) if $help;
if ($gmail) {
$foldername = 'Notes';
$folder_opts{'server_name'} = 'imap.gmail.com';
$folder_opts{'type'} = 'imaps';
}
pod2usage("must specify a --folder")
unless defined $foldername;
pod2usage("Can not use more then one of --create, --modify, --delete")
if (1 < $create + $modify + $delete);
pod2usage("Must specify one of --create, --modify, --delete")
if (0 == $create + $modify + $delete);
pod2usage("must specify a --uuid to use --modify or --delete")
unless ($create or defined $uuid);
my $mgr = Mail::Box::Manager->new;
# really wish Mail::Box impls registered themselves by default
if (exists $folder_opts{'type'} and $folder_opts{'type'} eq 'imaps') {
$mgr->registerType('imaps' => 'Mail::Box::IMAP4::SSL');
}
my $folder = $mgr->open($foldername, %folder_opts)
or die "Can't open folder: $foldername\n";
if ($modify or $delete) {
# find the existing message
# Ugh, gmail doesn't seem to support whatever Mail::Box::Search::G
+rep
# tries to do to find messages with a specific header name=val
my @matches =
grep { $_->head->get(UUID_HEADER()) eq $uuid } $folder->messages()
+;
my $num = scalar @matches;
if (1 < $num) {
die "Found too many messages: $num";
} elsif ($num < 1) {
die "Didn't find any matches";
}
# delete now, add a new one later
$matches[0]->delete();
}
if ($create or $modify) {
# create the "new" message
$uuid = Data::UUID->new()->create_str()
unless defined $uuid;
my @lines = <STDIN>;
my $subject = $lines[0];
chomp $subject;
my $msg = Mail::Message->build
( UUID_HEADER() => $uuid,
TYPE_HEADER() => TYPE_VALUE,
SUBJ_HEADER() => $subject,
'data' => \@lines,
);
$mgr->appendMessage($folder, $msg);
$folder->close();
$mgr->close();
}
__END__
=head1 NAME
iphonenote.pl - Manipulate iPhone notes in a mail folder
=head1 SYNOPSIS
iphonenote.pl -f folder -c [-u uid] < somefile.txt
iphonenote.pl -f folder -m -u uid < somefile.txt
iphonenote.pl -f folder -d -u uid
iphonenote.pl --gmail --opts username=foo@gmail.com --opts password=s
+3cr3t ...
Options:
-h or --help Print help documentation
-f or --folder The Mail::Box::Manager compliant foldername to mani
+pulate
-u or --uuid The UUID of the specific note to manipulate in that
+ folder
-c or --create To create a new note
-m or --modify To modify an existing note (requires --uuid)
-d or --delete To delete an existing note (requires --uuid)
--opts key=val pairs of Mail::Box options
-g of --gmail sets default -f and --opts for using gmail