Beefy Boxes and Bandwidth Generously Provided by pair Networks BBQ
Problems? Is your data what you think it is?
 
PerlMonks  

Manipulate iPhone 'Notes' folders

by hossman (Prior)
on Jul 26, 2010 at 05:12 UTC ( #851322=CUFP: print w/ replies, xml ) Need Help??

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.

UPDATE: Added options for making it work better with remote IMAP servers, particularly gmail.

#!/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

Comment on Manipulate iPhone 'Notes' folders
Download Code
Re: Manipulate iPhone 'Notes' folders
by eclpmb (Pilgrim) on Jul 27, 2010 at 07:54 UTC

    This sounds like something I could really make use off, but I'm not familiar with 'Mail::Box::Manager' and I'm not entirely sure from reading the perldoc what I should be putting in.

    I was guessing it wants the URL syntax - 'imap4://username:password@host/' - is that correct? If so can anyone tell me how to handle a username with an '@' symbol in please?

    Lastly is there a way to change the URL to use SSL?

      For SSL-imap it's imaps://. For some IMAP servers, I think you can replace @ with % in the URL like this:

      imaps://corion%corion.net@imap.corion.net

      ... would try to log in as corion%corion.net on imap.corion.net, and I think some IMAP servers understand that by %corion.net you really meant @corion.net.

      Personally, i run the script on my Mail server (using the local mailboxes) and only the iPHone deals with the notes via IMAP

      That said: i just tried it over IMAP, and it looks like Mail::Box::Manager may have a bug dealing with usernames that contain an "@" character. You should be able to URL escape the "@" symbol in the username, such that these properties...

      • user: yourname@maildomain.tld
      • pass: my$ecret
      • imap server: imap.domain.tld
      • port: 6789
      • folder: Notes

      ...become this url: imap://yourname%40maildomain.tld:my%24ecret@imap.domain.tld:6789/Notes

      But apparently Mail::Box::Manager can't deal with having a port and a password in that URI (even though that's what it's docs say to do). It fails with an error that "yourname" isn't a valid hostname

      My guess is only the "URL parsing" logic in Mail::Box::Manager is broken, you could probably customize the script to make it take in distinct user/pass/server/port params for IMAP and construct the folder programaticly

      I recently switched to using Google as my primary mail server, and had to revisit this problem (as well as making it work with IMAPS, and dealing with GMail's dislike of Mail::Box::Search::Grep)

      So I added some options to make deal with all of this, for instance...

      iphonenote.pl -c --opts type=imaps \ --opts server_name=imap.gmail.com \ --opts username=you@gmail.com \ --opts password=s3cr3t -f Notes < note.txt OR iphonenote.pl -c --gmail \ --opts username=you@gmail.com \ --opts password=s3cr3t < note.txt

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://851322]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2014-04-19 02:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (475 votes), past polls