Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Manipulate iPhone 'Notes' folders

by hossman (Prior)
on Jul 26, 2010 at 05:12 UTC ( [id://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 --help for usage # # $Id: 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 => ''; 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'} = ''; $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 - Manipulate iPhone notes in a mail folder =head1 SYNOPSIS -f folder -c [-u uid] < somefile.txt -f folder -m -u uid < somefile.txt -f folder -d -u uid --gmail --opts --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

Replies are listed 'Best First'.
Re: Manipulate iPhone 'Notes' folders
by eclpmb (Hermit) 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:


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

      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... -c --opts type=imaps \ --opts \ --opts \ --opts password=s3cr3t -f Notes < note.txt OR -c --gmail \ --opts \ --opts password=s3cr3t < note.txt
Re: Manipulate iPhone 'Notes' folders
by hossman (Prior) on May 12, 2015 at 17:07 UTC

Log In?

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (2)
As of 2024-07-21 22:09 GMT
Find Nodes?
    Voting Booth?

    No recent polls found

    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.