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:
- gphoto2-fuse-fs by Christopher Lester, this was the main inspiration for my code and uses the same techniques. Unfortunately the fuse api has changed since this was written and people with newer systems are unlikely to be able to get this code working.
- gphotofs by Philip
Langdale, this appears to have been written at almost exactly the same
time I started working on my code! It does exactly the right thing in
terms of interfacing with the camera and is the main project you
should bet on. At the moment it's not quite as functional as my
code (mkdir, display of fileperms for example) but mine is a quick
hack, this is the right way forward. Keep an eye on this
project.
Update (2006-03-06): The latest libgphoto2 failed to work with this or my project. After some debugging I found this was caused by the primitive usb-storage support they have added scanning all mounted filesystems. Yes, including the ones you've just created via FUSE. I fixed this hang by moving the disk.* files out of /usr/(local/)/lib/libgphoto2_port/*/ - but also forced my perl to assume usb for the gphoto2 calls so, for some people, this is the only version that will work out of the box.
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.