Damion Yates

Perl based gphoto2 filesystem project page

fusegphoto2 is a perl script that uses the Fuse perl bindings to mount a gphoto2 compatible camera as a filesystem.
Download fusegphoto2.

It is loosely based on FuseFTP, a perl based ftp mounting script (note: FTPFS from the lufs project, pre-FUSE can be used via the LUFS bridge and is probably much faster - http://fuse.sourceforge.net/wiki/index.php/FileSystems).

There are two other projects that provide the same functionality:

Usage (simple) :

mkdir a ; perl ./fusegphoto2-0.3-dmy.pl a

Usage (detailed) :

Make sure you have fuse installed. Make sure you've downloaded, compiled and installed the fuse-perl bindings. Make sure you can invoke

gphoto2 -l

and get a listing of directories of your camera.

hostname:~/fusegphoto2-0.3-dmy$ perl fusegphoto2 --help

Usage: fusegphoto2 [options] mountpoint 

where options is one of:

  --debug             Enable FUSE debugging messages
                      (implies --foreground)

  --xvpics            Enable virtual .xvpics/ directory for xv thumbnails

  --foreground        Don't put process into background

  --options=opt[,opt] Pass options to FUSE
                      allow_others: allow access by other users

Mountpoint is the directory where the camera's filesystem will be mounted into
the filesystem.

Features: mkdir, rmdir, deleting files, opening (for read only at the moment) files, listing files in directories with correct fileinfo (including perms, sizes and dates). A virtual .xvpics/ directory for zgv/xzgv and the ubiquitous XV (the standard X image viewer)

Go right to the downloads directory


Development story

I read about gphoto2-fuse-fs a while back and added trying that out to my todo list. A long time later while getting extremely annoyed with the klunky gtkam and gphoto2 interfaces I decided to grab the code and install it.

I'd read about how it spawns gphoto2 the cmdline binary via C system() calls and thought it sounded like my sort of program ;) . Unfortunately it was coded against an old fuse API and after a number of hours digging through the C, I gave up and emailed the author.

He's very friendly but he's lost his usb cable and won't be working on his code for the moment, we agreed that I'd be better off going for my new plan of using the perl fuse bindings. My C is rusty and I find perl very fast and simple for coding quick projects, you could call it prototyping if you like. The main bottle necks I assume are the usb and camera speed, so spawning a small binary for various fileIO operations in the perl process shouldn't be an issue I thought.

I'd seen the perl-fuse code a while back and had wonder what magic you could do with it... perhaps /proc like filesystems allowing you to eval arbitrary perl code by just touching files or making directories. Anyway, I was going to write a wrapper around Zip::Archive using Fuse.pm so I could update .zip (and maybe .tgz) files (the other fuse filesystems for this are r/o), but gphoto2 jumped to the top of the queue as I had a more urgent need.

I browsed around for example code and found fuseftp, this made the whole job look quite trivial. Sure enough after sorting all the dependancies out (not too nasty in the world of slackware) I'd confirmed his code worked exactly like it says on the tin and set about butchering it for my own uses.

A few hours of quick prototype coding and debugging later and I'd got most of the functionality, directory lookups and traversal. I wasn't sure about dealing with caching of files, the ftp code didn't seem as useful to me.

A fair emount of time was spent looking at the various options you get out from gphoto2, I'd managed to avoid the need to recompile the main binary with a quick kludge to display bytes rather than K which gphoto2-fuse-fs requires. I cache the output of

gphoto2 -f $dir --show-info 1-16384

filling an array with most of what you need for a stat() for each file in a directory, 16384 is the maximum files gphoto2 can deal with in a -f specified directory, the command finishes quickly and stops after the last file in any directory so it's all good. This provides date/time, read/delete perms and filesize in bytes.

There was much more of this playing, with the .xvpics/ kludge being the most recent addition, involving hours of searching for a way to generate files that are recognised by XV (/bin/file shows: "Netpbm PAM image file"). This was harder than I'd thought, I couldn't confirm Image::Magick (perl) could do it, netpbm tools were unclear, but implied they could only convert away from pam, and possibly that XV pam was incompatlble, anyway the manpages were unclear and no invocation of any of the compiled netpbm tools gave me what I wanted. I then found that "P7" was what the format was known as in the ImageMagick world, and that the cmdline tool mogrify could dynamically parse files out in the right format.

This is currently too slow, so if I do any more work on the code (see above about how I say gphotofs is the way forward) it'll be to speed this up, probably caching a full directory thumbnail output rather than doing it one file at a time.

Anyway rather than go on and on, you should look at the code, it's simple perl and most of the `` spawned gphoto2 lines are quite obvious.