iPhoto – Removing redundant originals

I recently came across this article on slimming down an iPhoto library by removing the ‘Original’ photo where a ‘Modified’ one existed.

(That’s one part of what the free iPhoto Diet app does, but it seems that’s not being maintained and doesn’t support recent versions of iPhoto.)

Inspired by the basic three-line shell script in the article I worked up this somewhat more advanced version:

#!/bin/sh -ex
cd ~/Pictures/
du -sh 'iPhoto Library'
dest=$HOME/Pictures/iPhoto-Redundant-Originals-`date "+%Y-%m-%d-%H%M"`
# for all files in iPhoto Library/Modified/...,
# move the corresponding iPhoto Library/Originals/...
# files into a zip archive file
find 'iPhoto Library/Modified' -type f -print \
    | perl -pe 's{iPhoto Library/Modified/}{iPhoto Library/Originals/}' \
    | zip -9 -T -m $dest -@ 2>&1 \
    | grep -v 'zip warning: name not matched'
du -sh 'iPhoto Library'

It has some advantages over the original: the photos are moved into a unique zip file, rather than the trash, and the file hierarchy is preserved, so files can be restored easily.

It could be modified to only operate on a subset of files, such as those older than a certain age.

Extra notes:

  1. After running this you’ll find that the photo will appear black in the ‘edit view’. That’s not a problem. The ‘edit view’ (which you enter by double clicking on a photo, for example) reconstructs the final image by taking the original and reapplying the edits-so-far. Since the original file has been removed you’ll just see a black image. Don’t worry. In all the other views, and for printing etc., your final modified picture will appear perfectly.
  2. iPhoto handles automatic rotation of images from cameras that record their orientation by performing a rotation ‘edit’ for you when you import the image. That rotation creates a modified copy, and that’s a common cause of bloat in your iPhoto library. It’s also why you may be surprised to see some originals being archived even though you haven’t editied them. It would be nice if iPhoto had an option to handle rotations destructively.

Usual caveats: this worked for me, your mileage may vary, cross your fingers, read the referenced article (and follow the links in contains), read the comments on them, quit iPhoto, take a backup, wear a tinfoil hat.

Examples of Modern Perl

In the spirit of re-tweeting, this is a short post to highlight some great examples of “modern perl”. (I’m using the term modern perl very loosely, not referring specifically to any one book, website, or module or organization.)

Firstly I’d like to highlight a couple of recent posts by Jonathan Rockway:

* Unshortening URLs with Modern Perl (also available here). An interesting example application built with modern perl modules like MooseX::Declare, MooseX::Getopt, HTTP::Engine, AnyEvent::HTTP, TryCatch, and KiokuDB.

* Multimethods. Another great example from Jonathan highlighting the combined power of MooseX::Types, MooseX::Declare, and MooseX:: MultiMethods.

Then, from his work at the BBC, Curtis “Ovid” Poe has given us a great series of thoughtful posts on the benefits of replacing multiple inheritance with roles in a complex production code-base. The slides of his Inheritance vs Roles talk is a good place to start. Then dive in to the blog posts back here and work your way forward.

I ♥ modern perl!

Generate Treemaps for HTML from Perl, please.

Seeing this video of treemap for perlcritic memory usage reminded me of something…

I’d really like to be able to use treemaps in NYTProf reports to visualize the time spent in different parts, and depths, of the package namespace hierarchy. Currently that information is reported in a series of tables.

A much better interface could be provided by treemaps. Ideally allowing the user to drill-down into deeper levels of the package namespace hierarchy. (It needn’t be this flashy, just 2D would be fine :-)

In case you’re not familiar with them, treemaps are a great way to visualise hierarchical data. Here’s an example treemap of the disk space used by the files in a directory tree (from schoschie) 82244D56-FA2C-4044-AE46-EE53B63861BE.jpg

Perl already has a Treemap module, which can generate treemap images via the Imager module. Treemap is designed to support more output formats by sub-classing.

I guess it wouldn’t be hard to write a sub-class to generate HTML client-side image map data along with the image, so clicks on the image could be used to drill-down into treemaps that have more detail of the specific area that was clicked on.

More interesting, and more flexible, would be a sub-class to generate the treemap as a Scalable Vector Graphics diagram using the SVG module (and others).

I’m not going to be able to work on either of those ideas anytime soon.

Any volunteers?

Perl DynaLoader hack using .bs files

I needed to install a perl extension from a third-party. It’s an interface to a shared library, a .so file, that they also supply.

Normally I’d add the directory containing the shared library to the LD_LIBRARY_PATH environment variable. Then when the extension is loaded the system dynamic loader can find it.

For various reasons I didn’t want to do that in this case.

An alternative approach is to pre-load the shared library with a flag to make it’s symbols globally available for later linking. (The flag is called RTLD_GLOBAL on Linux, Solaris and other systems that use dlopen(). This hack may not work on other systems.)

But how to pre-load the shared library, only when needed, and without changing any existing perl code? This is where the pesky little .bs files that get installed with perl extensions come in handy.

They’re known as ‘bootstrap’ files. If the .bs file for an extension not empty then DynaLoader (and XSLoader) will execute the contents just before loading the shared object for the extension.

So I put code like this into the .bs file for the extension:

    use DynaLoader;
    DynaLoader::dl_load_file("$ENV{...}/...so", 1)
	    or die DynaLoader::dl_error();

Not a recommended approach, but neat and handy for me in this case.

NYTProf 2.09 – now handles modules using AutoLoader, like POSIX and Storable

I’ve uploaded Devel::NYTProf 2.09 to CPAN.

If you’re using VMS the big news is that Peter (Stig) Edwards has contributed patches that enable NYTProf to work on VMS. Yeah! Thanks Peter.

For the rest of us there’s only one significant new feature in this release: NYTProf now includes a heuristic (that’s geek for “it’ll be wrong sometimes”) to handle modules using AutoLoader. The most common of which are Storable and POSIX. You may have encountered a warning like this when running nytprofhtml:

Unable to open '/../../lib/Storable.pm' for reading: No such file or directory

It’s a symptom of a deeper problem caused by AutoSplit, the companion to AutoLoader. The details of the cause, effect, and fix aren’t worth going into now. If you’re interested you can read my summary to the mailing list.

The upshot is that NYTProf now reports times for autoloaded subs as if the sub was part of the parent module. Just what you want. Time spent in the AUTOLOAD’er sub is also reported, naturally.

There is a small chance that the heuristic will pick the wrong ‘parent’ module file for the autoloaded subroutine file. That can happen if there are other modules that use the same name for the last portion of the package name (e.g., Bar::Foo and Baz::Foo). If it ever happens to you, please let me know. Ideally with a small test case.

The list of changes can be found here (or here if you’re a detail fanatic).

One other particularly notable item is that the savesrc option wasn’t working reliably. Thanks to Andy Grundman providing a good test case, that’s now been fixed.

Enjoy!

Retreat

I usually get a cold around January. Nothing major, gone in a week or so. This year I excelled myself by succumbing to the ’flu and following it up with assorted complications. January was mostly a write-off, February was better but still a struggle (what with jet lag and unexpected surprises). Fortunately my Functional Biochemistry practitioner has pinpointed the underlying cause for the slow recovery and I’m fast returning to my usual good health.

My wife suggested I take some time-out for myself. After the rough few weeks I needed a boost, so I did…

I’m just back from a wonderful two day retreat organized by Timothy and Eva from the Kalyana Centre for Mindfulness in Co. Kerry.

The retreat was held in silence, practising Kum Nye, a Tibetan Buddhist movement practice. It was lead by Matthias Steurich — a rare opportunity to practice with him in Ireland. It was wonderful. Just what I needed.

The location was beautiful. A large house overlooking Inch Strand in County Kerry in the West of Ireland. I took this photo on my iPhone on one of my walks along the beach:

IMG_0303.JPG

NYTProf screencast from the 2008 London Perl Workshop

I’ve uploaded the screencast of my NYTProf talk at the London Perl Workshop in November 2008.

It’s based on a not-quite-2.08 version and includes some coverage of an early draft of the ‘timings per rolled-up package name’ feature I discussed previously.

It also shows how and why anonymous subroutines, defined at the same line of different executions of the same string eval, get ‘merged’.

The demos use perlcritic and Moose code. It also includes a nice demonstration showing NYTProf highlighting a performance problem with File::Spec::Unix when called using Path::Class::Dir objects.

It’s 36 minutes long, including a good Q&A session at the end (wherein a market rate for performance improvements is established). Enjoy.