将命令行函数的标准输出发送到python StringIO对象

时间:2013-07-21 22:48:19

标签: python django amazon-s3 imagemagick

哇,很难将我的问题封装在一个简洁的标题中。我希望我能成功。

我有一个简单的缩略图功能,当我尝试从Amazon S3检索URL,然后使用ImageMagick convert时,我会遇到问题。我通常会使用PIL读取图像文件并进行转换,但PIL不会读取PDF格式,因此我正在通过子进程调用进行转换。

这是来自django views.py的一些代码。这里的想法是我从S3获取文件URL,用convert打开它,将其处理成PNG,发送到stdout,然后使用输出的缓冲区加载StringIO对象,然后传递给它返回default_storages将缩略图文件保存回S3。对于这么简单的工作来说真的很好,但是你去了。

请注意:在使用Heroku的生产设置中,我无法使用convert将文件可靠地保存到磁盘,否则,我已经这样做了。

def _large_thumbnail_s3(p):

    # get the URL from S3, trimming off the expiry info etc. So far so good.

    url = default_storage.url(p+'.pdf').split('?')
    url = url[0]

    # this opens the PDF file fine, and proceeds to convert and send 
    # the new PNG to the buffer via standard output.

    from subprocess import call 
    call("convert -thumbnail '400x600>' -density 96 -quality 85 "
        +url
        +" png:-", shell=True)

    from StringIO import StringIO

    # here's where the problem starts. I'm clearly not reading
    # in the stdout correctly, as I get a IOError: File not open for reading
    # from this next line of code:

    completeStdin = sys.stdout.read()
    im = StringIO(completeStdin)

    # now take the StringIO PNG object and save it back to S3 (this 
    # should not be an issue.

    im = default_storage.open(p+'_lg.png', 'w+b')
    im.close()

任何人都可以告诉我a)在将输出发送回缩略图功能方面我可能会出错的地方,以及b)你是否可以建议任何更强大的替代方法,这似乎是一种非常糟糕的方式!

TIA

1 个答案:

答案 0 :(得分:1)

您需要使用subprocess.check_output,而不是subprocess.call

from subprocess import check_output
from StringIO import StringIO

out, err = check_output("convert -thumbnail '400x600>' -density 96 -quality 85 "
    +url
    +" png:-", shell=True)

buffer = StringIO(out)