The Ubuntu distro package contains an excellent photo viewer application – since the Maverick release this application is Shotwell, replacing the earlier F-Spot. Shotwell is a great application – but I came across a rare and extremely annoying problem – under certain circumstances, involving removable media, the application would lose the “events” to which your pictures are assigned. The only way (up to now) to fix this, is to re-import all your images. I have 32 000 photos. So I created a solution. Here it is.
Shotwell is written in a language called Vala, which “targets GNOME’s object system”. AFAIK Vala is not very widely used – I certainly have little knowledge of it. Fortunately Shotwell uses SQLite as a back-end, and uses a very simple database schema to boot.
When one initially imports data into Shotwell, it creates a set of events, based on the exposure times of the photos being imported. This is extremely useful when navigating through thousands of images. The problem I experienced is that, after starting up Shotwell while the drive on which my photos are stored was unmounted, Shotwell deleted all the links between events and photos. This is a serious (but rare) bug, which has been reported here. Some of the event data was preserved in the database, but the foreign keys were all reset. Unfortunately Shotwell does not offer any way of recreating events manually (at least not in version 0.7.2). I was faced with the prospect of importing 30 000+ photos (several hours) or writing a script to fix the database (also several hours, but much more fun).
After a brief examination of the database it became clear that events in Shotwell are persisted in “EventTable” – a simple table that stores the id of a “primary photo”, as well as a unique event id. The primary photo is the photo that is displayed when the events are rendered in Shotwell. Each photo in “PhotoTable” belongs to an event.
The Shotwell source code is freely available, and I took a look at the code for the Events class – you can find it here: http://trac.yorba.org/browser/shotwell/.
Although there are some complications in the code related to determining a boundary hour for all images, I decided to keep it simple and use midnight as the cut-off.
A relatively straightforward Python script sufficed to re-create all the events. I initially wrote a procedure to attempt and recover the data fragments that were left in the EventsTable – even though this was successful, the data was incomplete and not all events were recovered.
You can download the script here as a text file (rename to .py) -ShotFix
The main loop works as follows – it is very straightforward:
select all photos, ordering by time
for every photo
retrieve exposure date
is exposure date in event list?
YES: add existing event id to photo
NO: create new event id and add to photo
next photo
A few notes:


1 response so far ↓
1 Bas // Dec 11, 2011 at 10:40 pm
Thx, the issue seems to arise if the import was stopped early (e.g. a network connection issue that broke my x-communication).
The script fixed it.
Leave a Comment