Hold On A Minute
September 9th, 2010One of the big new features in MarsEdit 3 is a revamped media manager that allows you to easily browse local libraries from iPhoto, Aperture, etc.
This functionality is based largely on the great work of the iMedia project, which was spearheaded by Karelia to replicate Apple’s own ubiquitous media browsing interface, some variant of which is available in Pages, iWeb, Mail, etc.
iMedia has been around for a while, but in the past year or more it has been undergoing a significant overhaul as its primary developers gear up to release the official 2.0 milestone. I have been involved in the 2.0 project for a long time now as an “early adopter,” using MarsEdit as a testing ground during the beta phase, and taking (mostly!) only the refined and polished aspects of the product for the final MarsEdit 3.0 release.
We are still ironing out some of the kinks, especially in parts of the project that were not tested in MarsEdit. One of the cool new features is support for the Flickr photo-sharing service. Like MarsEdit’s own Flickr-browser, it shows thumbnails of images on Flickr, and lets you treat them more-or-less like ordinary image files that you’d find on your computer.
Things get a little bit complicated when a user selects and drags one of these Flickr image thumbnails to another app, such as the Finder, or Photoshop. Since the image lives in the internet, and not on the local hard disk, it is not something that can be popped over to the application in an instant. Instead, a progress dialog comes up while the image is downloaded to the disk, and then the local copy is passed to the receiving application.
I try to contribute back when possible in the form of bug fixes and architectural feedback. Some of the work I did for iMedia 2.0 involved updating its drag-and-drop functionality to take advantage of new features in Mac OS X 10.6. In the process, I became a sort of de facto expert on handling dragging, which is a shame, because we could sure use a real expert, instead!
The other day, an issue came up that relates to the dragging of Flickr files. If the download is taking a while, and the user tries to cancel, mouse clicks are apparently ignored and they are stuck with the progress dialog above. I agreed to look into the issue, but there was just one problem: my network is too fast! Whenever I try to drag a Flickr image to another app, it’s done within a couple seconds, and I don’t have time to play around with clicking the cancel button.
If only I could get a really slow connection to Flickr, then I could easily test this. In the old days of Mac OS 9 or earlier, I may have resorted to plugging in a slow modem to simulate the experience of the less bandwidth-fortunate. In Mac OS X however, I can take advantage of the advanced firewall software that comes bundled with the operating system, and which allows me to configure “traffic shaping” policies on the traffic coming in and out of my computer. I found a great hint from Macworld that got me on the right track.
My goal is to cause Flickr downloads to be artificially slow. In order to achieve this goal I need to find the specific web address that the downloads come from. To do this, I use the standard tcpdump terminal utility, which also comes bundled with Mac OS X:
sudo tcpdump -Atqp -s 0 -ien1
The only part you may want to change is the bit at the end that says “en1”. Depending on the network interface you’re using, you might want en0 or en2 instead. With this running in the terminal, I go back to iMedia and start downloading Flickr files. This lets me see what the addresses of those files look like, and I discover the pertinent host name is “farm5.static.flickr.com”. Using the information I gleaned from the Macworld article, I set up the following firewall traffic shaping rules:
sudo ipfw pipe 1 config bw 15KByte/s sudo ipfw add 1 pipe 1 src-port 80 src-ip farm5.static.flickr.com
Translation?
- Create a pipe (you might prefer to call it a “tube”). A pipe is an artificial pass-through which can be configured to slow down, block, or otherwise alter the network traffic that goes through it.
- Configure the pipe to limit bandwidth to a crawling 15KByte/s.
- Configure all traffic coming from port 80 (the standard HTTP port), and originating from a specific hostname at Flickr, to pass through that pipe.
As soon as these commands are executed, the pipe is in place, and Flickr download speeds are brought to screeching halt. I can now debug the issue with the download dialog and the cancel button patiently and curiously, instead of racing to try clicking the button while I still have the chance.
When I’m done debugging, I definitely want to delete the pipe, so that download speeds go back to normal:
sudo ipfw delete 1
Mucking around with the built-in firewall on Mac OS X is not for the extremely faint-of-heart. This is why all the commands listed in this entry require “sudo” superuser privileges. Yes, you could seriously screw up your computer’s network connection if you do something wrong. But if you are the type of person whose work requires you to test and debug network related tasks, this traffic shaping functionality can be a real asset when it comes to mimicking the network environments of other people.
Addendum: I should have known I might be doing it the hard way, as usual. Clint Ecker reported on Twitter, and several folks in the comments below, that speedlimit, a Mac OS X preference pane, gets the job done in a much friendlier manner.
September 9th, 2010 at 2:12 pm
Daniel, great write-up on a nice subject … I’d heartily recommend keeping a copy of WaterRoof (http://www.hanynet.com/waterroof/) handy if you want to delve into the IPFW setup on OSX. Its nice now and again to have the GUI to help with the rulesets!
BTW, take note of the warning about traffic shaping and 64bit OSX kernel panics, some people may get bitten on 10.6.x …
CraigM
September 9th, 2010 at 2:12 pm
Be sure to take a look at Mike Schrag’s SpeedLimit: a .prefPane which wraps such firewall config hacking into a simple high-level GUI:
http://mschrag.github.com/#speedlimit
http://github.com/mschrag/speedlimit
September 9th, 2010 at 2:13 pm
For a more user-friendly version of the same thing, check out the speedlimit prefpane at http://mschrag.github.com/
Later,
Blake.
September 9th, 2010 at 2:15 pm
The way I handled a problem very similar to this is to run a nested event loop. This allows the user to interact with the UI and still block the promised file callback.
My loop was something like this:
while ([self shouldBlockTarget]) {
NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantFuture]
inMode:NSDefaultRunLoopMode
dequeue:YES];
[NSApp sendEvent:event];
[NSApp updateWindows];
}
When the copy finished or the user pressed Cancel I did the following:
// Post a dummy event so that we get kicked out of the event loop.
NSEvent *event = [NSEvent
otherEventWithType:NSApplicationDefined
location:NSZeroPoint
modifierFlags:0
timestamp:0
windowNumber:0
context:NULL
subtype:0
data1:0
data2:0];
[NSApp postEvent:event atStart:NO];
September 9th, 2010 at 2:18 pm
Nice tip.
Another very comfortable way to do this, as long as you’re dealing with HTTP only, is to use the Throttle feature of the Charles Web Proxy: http://www.charlesproxy.com/. This and all other features saved me countless hours of debugging time… Highly recommended if you do any application development that involves HTTP.
September 9th, 2010 at 2:21 pm
+1 For SpeedLimit (http://mschrag.github.com/). While I had to build it myself from source, the prefpane is easy to use and works wonders when trying to slow down an internet connection to specific hosts.
September 9th, 2010 at 10:17 pm
Great post, Daniel. I wish I had your too-fast-network problem. I guess the San Francisco Bay Area is too remote, thus the slow download speeds we have here. :-)
Hopefully we’ll get this dragging issue sorted out soon. In the meantime, I invite any developers who are interested to check out the project at http://imedia.googlecode.com/ and consider contributing to the code-base and/or incorporating it into their own projects. The 2.0 rewrite (thanks chiefly to Peter Baumgartner or Boinx, author of PhotoMagico) is just astonishing and quite a bit internal improvement from the 1.x version that is shipping in a number of applications.
September 9th, 2010 at 10:21 pm
Really great updates. One question: is it possible to add captions to photos from within MarsEdit?
September 10th, 2010 at 11:05 am
Hi Michael – the app doesn’t have any specific support for captions, but it’s sort of possible to achieve it using the customizable “media markup macros.” When you are inserting an image, look in the “Style” popup which by default just includes e.g. Align Left, Centered, etc. You can add custom markup items here that could, for example, contain a fancy HTML template that used, for example, the “Alt Text” you provide to show a caption beneath the image.
I’d like to add fancier image styling features right in the app at some point in the future.
September 10th, 2010 at 12:19 pm
Thanks, Daniel. I’ll give that a shot.