Skip to content

Instantly share code, notes, and snippets.

@ktuite
Created July 3, 2014 00:20
Show Gist options
  • Save ktuite/38ce9958dacd62dde4fd to your computer and use it in GitHub Desktop.
Save ktuite/38ce9958dacd62dde4fd to your computer and use it in GitHub Desktop.
Twisted server that serves up images in a directory
from twisted.web.resource import Resource
from twisted.web import server
from twisted.python import log
from twisted.internet import defer
import os
from datetime import datetime
from twisted.protocols.basic import FileSender
##########################
#### Global Variables ####
##########################
BASE_PATH = None
PORT = 8000
###################################
#### Root and utility resources ###
###################################
class RootResource(Resource):
def __init__(self):
Resource.__init__(self)
self.putChild('image', ImageRootResource())
class ImageRootResource(Resource):
def getChild(self, path, request):
try:
return ImageResource(path)
except ValueError:
return BadResource()
class ImageResource(Resource):
def __init__(self, image_key):
# key will be soemthing like 22_cropped
self.image_key = image_key
Resource.__init__(self)
def render_GET(self, request):
@defer.inlineCallbacks
def _showImage():
# Set up so that you type the name of the file without the extension
# e.g. host:port/image/photo to see file /path/to/file/photo.jpg
# could make it so the key is just the full name of the file, but then it can serve up anything
jpgpath = "%s/%s.jpg" % (BASE_PATH, self.image_key)
gifpath = "%s/%s.gif" % (BASE_PATH, self.image_key)
pngpath = "%s/%s.png" % (BASE_PATH, self.image_key)
print "Image path", jpgpath, gifpath, pngpath
@defer.inlineCallbacks
def _setContentDispositionAndSend(file_path, image_key, extension, content_type):
request.setHeader('content-disposition', 'filename="%s.%s"' % (image_key, extension))
request.setHeader('content-type', content_type)
f = open(file_path, "rb")
yield FileSender().beginFileTransfer(f, request)
f.close()
defer.returnValue(0)
if os.path.exists(jpgpath):
yield _setContentDispositionAndSend(jpgpath, self.image_key, ".jpg", "image/jpeg")
elif os.path.exists(gifpath):
yield _setContentDispositionAndSend(gifpath, self.image_key, ".gif", "image/gif")
elif os.path.exists(pngpath):
yield _setContentDispositionAndSend(pngpath, self.image_key, ".png", "image/png")
else:
request.setResponseCode(http.NOT_FOUND)
request.write("No such image '%s'" % request.path)
request.finish()
defer.returnValue(0)
_showImage()
return server.NOT_DONE_YET
##########################
#### Main! ###############
#### Go, little server! ##
##########################
if __name__ == "__main__":
from twisted.internet import reactor
from sys import stdout
import sys
from time import gmtime, strftime
log_file = "log_" + strftime("%Y-%m-%d_%H:%M:%S", gmtime()) + ".txt"
from twisted.python.log import FileLogObserver, startLogging, addObserver, msg
# First, startLogging to capture stdout
startLogging(stdout)
# Now add an observer that logs to a file
addObserver(FileLogObserver(open(log_file, "w")).emit)
if not BASE_PATH:
BASE_PATH = sys.path[0]
print "Base path for images is", BASE_PATH
reactor.listenTCP(PORT,server.Site(RootResource()))
log.msg("running...")
reactor.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment