#!/usr/bin/perl
use warnings;
use strict;

# This downloads all files in the 'Images' folder on a phone into
# a new directory, which is automatically created using the current
# date.  The images will be deleted from the phone automatically.
# The modification timestamps of the downloaded files are set to
# what the phone reports.
#
# If you don't specify the bluetooth address of the phone then obexftp
# will scan for it.  That will probably work, but will be slower than
# specifying it.  The address should be a 12 digit hexadecimal number
# with a colon between every pair of digits.
#
# This has only been tested on a Nokia 6230i.
#
# Bugs: no way to override output directory, no way to load from a
# different directory on the phone, and no option to not delete from
# the phone.

use XML::LibXML;
use DateTime;

usage() if @ARGV > 1;
my $phone_addr = shift @ARGV;
usage() unless !defined $phone_addr ||
               $phone_addr =~ /^(?:[0-9A-Z]{2}:){5}[0-9A-Z]{2}$/i;

my $output_dir = DateTime->today->ymd;
die "$0: output directory '$output_dir' already exists\n"
    if -e $output_dir;

# Get a listing of files in the 'Images' folder.
# The hash maps files to modification times (as DateTime values).
my %file;
{
    open my $fh, '-|', 'obexftp',
                       '-b', (defined $phone_addr ? ($phone_addr) : ()),
                       '-l', 'Images'
        or die "$0: error running 'obexftp': $!\n";
    my $listing_xml = do { local $/; <$fh> };

    my $parser = XML::LibXML->new;
    $parser->line_numbers(1);
    my $doc = $parser->parse_string($listing_xml);

    for my $elem ($doc->findnodes('/folder-listing/file')) {
        my $filename = $elem->getAttribute('name');
        my $modified = $elem->getAttribute('modified');
        die "missing value in file"
            unless defined $filename && defined $modified;
        $modified =~ /^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)$/i
            or die "bad 'modified' value '$modified'";
        my $time = DateTime->new(
            year => $1, month => $2, day => $3,
            hour => $4, minute => $5, second => $6,
        );
        $file{$filename} = $time;
    }
}

# Actually download the images into a new directory.
mkdir $output_dir
    or die "$0: error creating output directory '$output_dir': $!\n";
chdir $output_dir
    or die "$0: error chdiring into output directory: $!\n";
system(qw( obexftp -v -b ), (defined $phone_addr ? ($phone_addr) : ()),
       qw( -c Images -G ), sort keys %file);

# Set the modification timestamps of the downloaded images
while (my ($filename, $modified) = each %file) {
    my $utime = $modified->epoch;
    utime $utime, $utime, $filename
        or warn "$0: error setting modification time of '$filename': $!\n";
}


sub usage
{
    die "Usage: $0 [phone-address]\n";
}

# vi:ts=4 sw=4 expandtab
