Separate out transforms and fetching logic to separate module; added Rotate transform
This commit is contained in:
parent
68b7cb7d3b
commit
b0191a67d4
|
@ -1,80 +1,15 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import Image
|
||||
import os
|
||||
import re
|
||||
import pdb
|
||||
import sys
|
||||
import time
|
||||
|
||||
from StringIO import StringIO
|
||||
|
||||
from eventlet import api
|
||||
from eventlet.green import urllib2
|
||||
from eventlet.green import BaseHTTPServer
|
||||
|
||||
class TransformException(Exception):
|
||||
pass
|
||||
from PILServ import fetch
|
||||
from PILServ import transforms
|
||||
|
||||
class BaseTransform(object):
|
||||
command = None
|
||||
@classmethod
|
||||
def execute(cls, path, out):
|
||||
raise TransformException('Subclasses of BaseTransform must override execute()')
|
||||
|
||||
@classmethod
|
||||
def parsePositionals(cls, rawbuf):
|
||||
if not rawbuf:
|
||||
return []
|
||||
return [p.strip() for p in rawbuf[1:-1].split(',')]
|
||||
|
||||
class Resize(BaseTransform):
|
||||
command = 'resize'
|
||||
@classmethod
|
||||
def execute(cls, infile, args, **kwargs):
|
||||
args = cls.parsePositionals(args)
|
||||
return cls._execute(infile, *args, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def _execute(cls, infile, size, **kwargs):
|
||||
if not size:
|
||||
size = (64, 64)
|
||||
else:
|
||||
size = tuple(size.split('x'))
|
||||
outfile = StringIO()
|
||||
im = Image.open(infile)
|
||||
im.thumbnail(size)
|
||||
im.save(outfile, 'png')
|
||||
return outfile.getvalue()
|
||||
|
||||
class Flip(BaseTransform):
|
||||
command = 'flip'
|
||||
@classmethod
|
||||
def execute(cls, infile, args, **kwargs):
|
||||
args = cls.parsePositionals(args)
|
||||
return cls._execute(infile, *args, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def _execute(cls, infile, *args, **kwargs):
|
||||
outfile = StringIO()
|
||||
im = Image.open(infile)
|
||||
im = im.rotate(180, expand=True)
|
||||
im.save(outfile, 'png')
|
||||
return outfile.getvalue()
|
||||
|
||||
def __aggregate():
|
||||
module = sys.modules[__name__]
|
||||
for name in dir(module):
|
||||
attr = getattr(module, name)
|
||||
if not isinstance(attr, type):
|
||||
continue
|
||||
if not issubclass(attr, BaseTransform):
|
||||
continue
|
||||
if attr == BaseTransform:
|
||||
continue
|
||||
yield attr
|
||||
|
||||
transform_commands = dict(((t.command, t) for t in __aggregate()))
|
||||
|
||||
class PILHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
nongreedy = '.*?'
|
||||
|
@ -87,16 +22,17 @@ class PILHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||
print ('do_GET', self.__dict__)
|
||||
m = self.url_regex.search(self.path)
|
||||
if not m:
|
||||
# No URL parsed out!
|
||||
return # XXX: Error condition
|
||||
|
||||
image = m.group(1)
|
||||
|
||||
# Grab the precending commands from the URL
|
||||
rest = self.path[:-(len(image))]
|
||||
commands = rest.split('/')
|
||||
|
||||
# Fetch image
|
||||
fd = urllib2.urlopen(image)
|
||||
image = fd.read()
|
||||
fd.close()
|
||||
# Fetch a string buffer representing the image
|
||||
image = fetch.fetchBuffer(image)
|
||||
|
||||
# Chain commands together
|
||||
for command in reversed(commands):
|
||||
|
@ -105,9 +41,11 @@ class PILHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||
args = self.arguments_regex.search(command)
|
||||
if args:
|
||||
args = args.group(1)
|
||||
# `command` is formatted like "resize(32x32)" here,
|
||||
# strip off the latter bits
|
||||
command = command[:-(len(args))]
|
||||
command = transform_commands.get(command)
|
||||
|
||||
command = transforms.commands.get(command)
|
||||
if not command:
|
||||
continue
|
||||
|
||||
|
@ -130,6 +68,3 @@ def main():
|
|||
return -1
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from eventlet.green import urllib2
|
||||
|
||||
|
||||
def __url(url):
|
||||
buf = None
|
||||
try:
|
||||
buf = urllib2.urlopen(url)
|
||||
return buf.read()
|
||||
finally:
|
||||
if buf:
|
||||
buf.close()
|
||||
|
||||
def fetchBuffer(url, cache=True):
|
||||
# Fetch image
|
||||
return __url(url)
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import Image
|
||||
import sys
|
||||
|
||||
from StringIO import StringIO
|
||||
|
||||
class TransformException(Exception):
|
||||
pass
|
||||
|
||||
class BaseTransform(object):
|
||||
command = None
|
||||
@classmethod
|
||||
def execute(cls, infile, args, **kwargs):
|
||||
args = cls.parsePositionals(args)
|
||||
return cls._execute(infile, *args, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def parsePositionals(cls, rawbuf):
|
||||
if not rawbuf:
|
||||
return []
|
||||
return [p.strip() for p in rawbuf[1:-1].split(',')]
|
||||
|
||||
class Resize(BaseTransform):
|
||||
command = 'resize'
|
||||
@classmethod
|
||||
def _execute(cls, infile, size, **kwargs):
|
||||
if not size:
|
||||
size = (64, 64)
|
||||
else:
|
||||
size = tuple(size.split('x'))
|
||||
outfile = StringIO()
|
||||
im = Image.open(infile)
|
||||
im.thumbnail(size)
|
||||
im.save(outfile, 'png')
|
||||
return outfile.getvalue()
|
||||
|
||||
|
||||
class Rotate(BaseTransform):
|
||||
command = 'rotate'
|
||||
@classmethod
|
||||
def _execute(cls, infile, angle, **kwargs):
|
||||
outfile = StringIO()
|
||||
im = Image.open(infile)
|
||||
im = im.rotate(float(angle), expand=True)
|
||||
im.save(outfile, 'png')
|
||||
return outfile.getvalue()
|
||||
|
||||
class Flip(Rotate):
|
||||
command = 'flip'
|
||||
@classmethod
|
||||
def _execute(cls, infile, *args, **kwargs):
|
||||
return Rotate._execute(infile, 180, **kwargs)
|
||||
|
||||
|
||||
def __aggregate():
|
||||
module = sys.modules[__name__]
|
||||
for name in dir(module):
|
||||
attr = getattr(module, name)
|
||||
if not isinstance(attr, type):
|
||||
continue
|
||||
if not issubclass(attr, BaseTransform):
|
||||
continue
|
||||
if attr == BaseTransform:
|
||||
continue
|
||||
yield attr
|
||||
|
||||
commands = dict(((t.command, t) for t in __aggregate()))
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import PILServ
|
||||
|
||||
if __name__ == '__main__':
|
||||
PILServ.main()
|
||||
|
Loading…
Reference in New Issue