Changeset 174


Ignore:
Timestamp:
05/02/05 03:08:27 (16 years ago)
Author:
Nicholas Riley
Message:

screenshot.py: Much better error handling, including dealing with
screencapture not always reporting errors by exit code
(rdar://problem/4104545). Generate (single) PNGs directly on Tiger -
untested.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/1001Screenshot/screenshot.py

    r171 r174  
    1010from LaunchServices.Launch import LSSetExtensionHiddenForRef
    1111
    12 def check(retval):
    13     if retval != 0:
    14         sys.exit(retval)
     12class HandledError(Exception):
     13    def __init__(self, args, message, retval):
     14        # make the arguments look distinct
     15        for index, arg in enumerate(args):
     16            if '\\' in arg:
     17                args[index] = args[index].replace('\\', '\\\\')
     18            if ' ' in arg:
     19                args[index] = '"%s"' % args[index].replace('"', '\"')
     20        description = 'An error occurred while attempting to execute the command %s' % ' '.join(args)
     21        if message:
     22            description += ':\n\n%s' % message
     23        else:
     24            description += '.\n'
     25        if retval:
     26            description += '\nThe process exited with status %d.' % retval
     27        Exception.__init__(self, description)
    1528
    16 def dumpPNG(pdf, pageNumber, outFileBase):
    17     if pageNumber is None:
    18         outFile = outFileBase + ".png"
    19         pageNumber = 1
    20     else:
    21         outFile = outFileBase + "-%03d.png" % pageNumber
     29def check(args, output, retval):
     30    if output:
     31        for index, line in enumerate(output):
     32            if line.lower().startswith('usage:'):
     33                output = output[:index]
     34                break
     35        raise HandledError(args, ''.join(output), retval)
     36    elif retval != 0:
     37        raise HandledError(args, '', retval)
    2238
    23     w = pdf.getTrimBox(pageNumber).getWidth()
    24     h = pdf.getTrimBox(pageNumber).getHeight()
    25 
    26     ctx = CGBitmapContextCreateWithColor(int(w), int(h), CGColorSpaceCreateDeviceRGB(), (0,0,0,0))
    27     ctx.drawPDFDocument(pdf.getTrimBox(pageNumber), pdf, pageNumber)
    28     ctx.writeToFile(outFile, kCGImageFormatPNG)
    29     return outFile
    30 
    31 tempDir = tempfile.mkdtemp()
    32 pdfFile = os.path.join(tempDir, 'screenshot.pdf')
    33 
    34 check(subprocess.call(['/usr/sbin/screencapture', '-iW', pdfFile]))
    35 
    36 pdf = CGPDFDocumentCreateWithProvider(CGDataProviderCreateWithFilename(pdfFile))
    37 numberOfPages = pdf.getNumberOfPages()
     39def execute(args):
     40    process = subprocess.Popen(args, stderr=subprocess.PIPE)
     41    retval = process.wait()
     42    check(args, process.stderr.readlines(), retval)
    3843
    3944desktopDir = FSFindFolder(kUserDomain, kDesktopFolderType, False).as_pathname()
    4045desktopContents = os.listdir(desktopDir)
    4146index = 1
    42 outFile = None
    43 while outFile is None:
    44     outFile = 'Screenshot %d' % index
     47outFileBase = None
     48while outFileBase is None:
     49    outFileBase = 'Screenshot %d' % index
    4550    for filePath in desktopContents:
    46         if filePath.startswith(outFile):
     51        if filePath.startswith(outFileBase):
    4752            index += 1
    48             outFile = None
     53            outFileBase = None
    4954            break
    50 outFile = os.path.join(desktopDir, outFile)
     55outFileBase = os.path.join(desktopDir, outFileBase)
     56writtenPaths = []
    5157
    52 writtenPaths = []
    53 if numberOfPages == 1:
    54     writtenPaths = [dumpPNG(pdf, None, outFile)]
     58SCREENCAPTURE_ARGS = ['/usr/sbin/screencapture', '-iW']
     59
     60outFile = outFileBase + '.png'
     61args = SCREENCAPTURE_ARGS + ['-tpng', outFile]
     62screencapture = subprocess.Popen(args, stderr=subprocess.PIPE)
     63retval = screencapture.wait()
     64output = screencapture.stderr.readlines()
     65
     66if retval == 1 and output and 'illegal option -- t' in output[0]:
     67    # Panther: only PDF output; Finder doesn't notice new files
     68    def dumpPNG(pdf, pageNumber):
     69        if pageNumber is None:
     70            outFile = outFileBase + ".png"
     71            pageNumber = 1
     72        else:
     73            outFile = outFileBase + "-%03d.png" % pageNumber
     74
     75        w = pdf.getTrimBox(pageNumber).getWidth()
     76        h = pdf.getTrimBox(pageNumber).getHeight()
     77
     78        ctx = CGBitmapContextCreateWithColor(int(w), int(h), CGColorSpaceCreateDeviceRGB(), (0,0,0,0))
     79        ctx.drawPDFDocument(pdf.getTrimBox(pageNumber), pdf, pageNumber)
     80        ctx.writeToFile(outFile, kCGImageFormatPNG)
     81        return outFile
     82
     83    tempDir = tempfile.mkdtemp()
     84    pdfFile = os.path.join(tempDir, 'screenshot.pdf')
     85
     86    execute(SCREENCAPTURE_ARGS + [pdfFile])
     87
     88    pdf = CGPDFDocumentCreateWithProvider(CGDataProviderCreateWithFilename(pdfFile))
     89    numberOfPages = pdf.getNumberOfPages()
     90
     91    writtenPaths = []
     92    if numberOfPages == 1:
     93        writtenPaths = [dumpPNG(pdf, None)]
     94    else:
     95        for pageNumber in xrange(1, numberOfPages+1):
     96            writtenPaths.append(dumpPNG(pdf, pageNumber))
     97
     98    os.remove(pdfFile)
     99    os.rmdir(tempDir)
     100
     101    for path in writtenPaths:
     102        LSSetExtensionHiddenForRef(FSPathMakeRef(path)[0], True)
     103
     104    # Carbon.File module doesn't implement FNNotify
     105    execute(['/usr/bin/osascript', '-e', 'tell app "Finder" to update desktop'])
    55106else:
    56     for pageNumber in xrange(1, numberOfPages+1):
    57         writtenPaths.append(dumpPNG(pdf, pageNumber, outFile))
    58 
    59 os.remove(pdfFile)
    60 os.rmdir(tempDir)
    61 
    62 for path in writtenPaths:
    63     LSSetExtensionHiddenForRef(FSPathMakeRef(path)[0], True)
    64 
    65 # Carbon.File module doesn't implement FNNotify
    66 subprocess.call(['/usr/bin/osascript', '-e', 'tell app "Finder" to update desktop'])
     107    check(args, output, retval)
     108    writtenPaths = [outFile]
    67109
    68110# LaunchServices module doesn't implement LSOpenFrom*Spec
    69 subprocess.call([os.path.join(os.getenv('RESOURCEPATH'), 'launch'), '-i', 'tv.kungfoo.1001'] + writtenPaths)
     111execute([os.path.join(os.getenv('RESOURCEPATH'), 'launch'), '-i', 'tv.kungfoo.1001'] + writtenPaths)
Note: See TracChangeset for help on using the changeset viewer.