I recently got a Palm Centro smartphone, and so far I love it. Like most modern cell phones, it has a built-in camera and takes decent snapshots and even records short movies. It’s great for spur-of-the-moment shots when I don’t have my real camera. The trick – and there’s always a trick when it comes to cell phones – is getting the photos off the camera and onto my computer.
To get at my pictures, Sprint would prefer that I sign up for their ludicrously expensive “PictureMail” service. Leave it to weasely telecom execs to come up with another way to squeeze money from teenagers: charge them $5 each month for the “privilege” of sharing their pictures with friends. This fee, of course, is in addition to the fee for “unlimited” mobile Internet use. I guess picture bits are somehow more expensive to move over the air than other kinds of bits.
In any case, my next goal after getting my Centro to hotsync with my Linux workstation was to figure out how to download my photos and movies.
After a bit of hacking, I figured out that the Centro stores images in a typical digital-camera-image (DCIM) hierarchy. For example, I have a 4-GB microSD card installed in my Centro, and I store my photos in the “Palm” album on it. This album ends up stored in the /DCIM/Palm directory on the card.
Using the pilot-xfer program from the pilot-link project, I was able to find the directory and its contents. The trick was to use the sparsely documented –D flag to work with the Centro’s virtual filesystem. Here, for example, is how I list the contents of the Palm album:
$ pilot-xfer -p usb: -D /DCIM/Palm -l Listening for incoming connection on usb:... connected! Directory of /DCIM/Palm... 652 Fri Nov 2 08:17:06 2007 Album.db 292053 Fri Nov 2 09:04:20 2007 Photo_110207_001.jpg 78493 Fri Nov 2 08:17:06 2007 Video_110207_001.3g2 20 Wed Oct 31 12:09:20 2007 Thumbnail.db Thank you for using pilot-link.
Here, you can see that I have one photo and one movie in the album. (Movies are stored in .3g2 files that contain MPEG4 video.)
To download the files, I again turned to pilot-xfer, this time using the –f (fetch) flag to fetch a list of files. Here, for example, I’ll fetch the image from the listing above:
$ pilot-xfer -p usb: -D /DCIM/Palm -f Photo_110207_001.jpg Listening for incoming connection on usb:... connected! Fetching '/DCIM/Palm' ... (292053 bytes) 285 KiB total. Thank you for using pilot-link.
So that’s the process. It’s kind of clunky, so I wrote a small Python program to automate it. (I’m learning Python. If you’re a Pythonista, please consider critiquing my code. I would be especially thankful if you could point out any helpful idioms that I may have overlooked.)
Here’s how to use the program:
$ get-pilot-photos.py --help Usage: get-pilot-photos.py [options] Options: -h, --help show this help message and exit -s SRCDIR, --srcdir=SRCDIR VFS dir on Palm device from which to fetch images -d DESTDIR, --destdir=DESTDIR Where to save the images on your computer
Both the —srcdir and —dstdir options are optional. If you omit the first, the program will download photos and movies from the /DCIM/Palm album. If you omit the second, the program will save the downloads to a new, timestamped directory within your home directory.
That’s it. The code is below.
<code style="font-size: smaller">#!/usr/bin/env python # get-pilot-photos.py - # Download photos and movies from my Palm Centro via pilot-link # # Tom Moertel <firstname.lastname@example.org> # 2007-11-01 # # Copyright 2007 Thomas G. Moertel # # This program is free software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of # the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # See <http://www.gnu.org/licenses/> for more. import os import optparse import re import subprocess import time PILOT_XFER = 'pilot-xfer' DEFAULT_PALM_IMAGE_DIR = '/DCIM/Palm' class PhotoImporter(object): def __init__(self, src_dir, dest_dir=None): self.src_dir = src_dir self.dest_dir = dest_dir or self.get_image_dir() def run(self): print 'Finding images in %s on your Palm device.' % self.src_dir print 'Begin hotsync now...' images = self.get_image_list() if len(images) == 0: print 'No images were found. Done.' return print 'Found %s images' % len(images) print 'Waiting for hotsync to complete...' time.sleep(10) # give 1st hotsync time to complete print 'Begin another hotsync now...' self.fetch_images(images) print 'Done. The images were fetched to the following directory:' print self.dest_dir def get_image_list(self): cmdline = [PILOT_XFER, '-p', 'usb:', '-D', self.src_dir, '-l'] proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE) listing = proc.stdout.read() proc.wait() return re.findall(r'\b\S+\.(?:jpg|3g2)\b', listing) def fetch_images(self, images): cmdline = [PILOT_XFER, '-p', 'usb:', '-D', self.src_dir, '-f'] + images subprocess.Popen(cmdline, cwd=self.dest_dir).wait() def get_image_dir(self): root = os.getenv('HOME') or tempfile.mkdtemp() now = time.strftime("%Y-%m-%d--%H.%M.%S", time.localtime()) dir = os.path.join(root, 'images', 'unsorted-pix', now) os.makedirs(dir, mode=0771) return dir def main(): p = optparse.OptionParser() p.add_option('--srcdir', '-s', default=DEFAULT_PALM_IMAGE_DIR, help='VFS dir on Palm device from which to fetch images') p.add_option('--destdir', '-d', help='Where to save the images on your computer') opts, args = p.parse_args() PhotoImporter(opts.srcdir, opts.destdir).run() if __name__ == '__main__': main() </code>