random($foo)

Printing with Python on OS X #

random($foo) is the personal site of Leonard Lin, where I collect shiny things and publish original writing and code. more »

Lately I’ve been doing more application programming. I’ve found that the best way to minimize the pain is to write as little Cocoa/Objective-C as possible. For example, here is a snippet is how you’d create a print job in Cocoa:

- (void)print:(id)sender {
[[NSPrintOperation printOperationWithView:self] runOperation];
}

- (void)printDocument:(id)sender {
// Assume documentView returns the custom view to be printed
NSPrintOperation *op = [NSPrintOperation
printOperationWithView:[self documentView]
printInfo:[self printInfo]];
[op runOperationModalForWindow:[self documentWindow]
delegate:self
didRunSelector:
@selector(printOperationDidRun:success:contextInfo:)
contextInfo:NULL];
}

- (void)printOperationDidRun:(NSPrintOperation *)printOperation
success:(BOOL)success
contextInfo:(void *)info {
if (success) {
// Can save updated NSPrintInfo, but only if you have
// a specific reason for doing so
// [self setPrintInfo: [printOperation printInfo]];
}
}

Yeah, I know, kill me now. My approach towards maintaining sanity and productivity has been to minimize these shenanigans by trying to use as little Cocoa as possible. Also, since I’ve come to [[really] disdain] Objective-C, doing the equivalent in Python was also high on my list. (That being said, I’ve also come to realize that writing Python and PyObjC is actually much worse than Objective-C and Cocoa.) What I really wanted was a pythonic way to print on OS X. The ideal scenario would be to import something and say be able to call printer.print() or something like that.

I wasn’t able to find anything like that. But, while I had originally dismissed lpr, it turned out that that was actually able to do what I needed. On OS X, lpr hooks right up to the CUPS used by the rest of the system and can be passed in not just text files, but PDFs and image files as well. Printing looks like this:

lpr -P [printer_name] file.jpg

There are several helpful commands like lproptions and lprstat that can help you with printer specific options. Here’s the CUPS documentation on Command-Line Printing and Options that’s quite useful.

So, the final code looks something like:

import popen2
popen2.popen4("lpr -P [printer] " + output_file)

  • joshrl

    I feel your pain with cocoa, but one nice thing about ObjC is that you can mix in regular old C, so why not just do a system call:

    - (void)print:(id)sender{
    system(“lpr…”)
    }

    Or if you want to go crazy you can use the cups c api directly:

    #include <cups/cups.h>
    - (void)print:(id)sender{
    cupsPrintFile(…);
    }

  • http://randomfoo.net/ lhl

    Good point about the C options. I'm actually doing most of my stuff in straight C where possible. I'm still a complete ObjC/Cocoa noob, so a lot of it is just pragmatic – being the most productive I can be and picking up what I need to when I am forced. In this case, the rest of my logic was already in Python so that just seemed like the easier way to go.

  • Avery

    Leonard,

    This is completely unrelated to this post, so my apologies up front, but this is the only way I can find to contact you about the awesome “polar bears for Obama” image you posted on flikr. My name is Avery and I live on DC and have been a loyal Obama supporter and I'm also a Bowdoin College alumnus. Our mascot is the polar bear and the issue of polar bear preservation is extremely close to our hearts. For the inauguration we have 20 Bowdoin students coming to stay with us and I would really like to have 20 Tshirts made up for these supporters of both Obama and polar bear preservation. We don't have any money to offer, but we can offer volunteer hours to the Obama campaign or greenpeace if you wouldn't mind our using the image you designed on our shirts. Of this ok with you please send me an email (averyash@Gmail.com) and I'd love to discuss getting a high res verion of your image. Thanks so much, and I look forward to hearing from you.

    Either way, fantastic design work.

    -Avery