<s> """<STR_LIT>""" <EOL> import mimetypes <EOL> import os . path <EOL> import logging <EOL> from webob import Request , Response <EOL> from paste import httpserver <EOL> from optparse import OptionParser <EOL> import platform <EOL> from StringIO import StringIO <EOL> import wsgiref . util <EOL> import hashlib <EOL> logger = None <EOL> class FileApp ( object ) : <EOL> def __init__ ( self , filename ) : <EOL> self . filename = filename <EOL> def __call__ ( self , environ , start_response ) : <EOL> res = make_response ( self . filename ) <EOL> return res ( environ , start_response ) <EOL> class FileIterable ( object ) : <EOL> def __init__ ( self , filename , start = None , stop = None ) : <EOL> self . filename = filename <EOL> self . start = start <EOL> self . stop = stop <EOL> def __iter__ ( self ) : <EOL> return FileIterator ( self . filename , self . start , self . stop ) <EOL> def app_iter_range ( self , start , stop ) : <EOL> return self . __class__ ( self . filename , start , stop ) <EOL> class FileIterator ( object ) : <EOL> chunk_size = <NUM_LIT> <EOL> def __init__ ( self , filename , start , stop ) : <EOL> self . filename = filename <EOL> self . fileobj = open ( self . filename , '<STR_LIT:rb>' ) <EOL> if start : <EOL> self . fileobj . seek ( start ) <EOL> if stop is not None : <EOL> self . length = stop - start <EOL> else : <EOL> self . length = None <EOL> def __iter__ ( self ) : <EOL> return self <EOL> def next ( self ) : <EOL> if self . length is not None and self . length <= <NUM_LIT:0> : <EOL> raise StopIteration <EOL> chunk = self . fileobj . read ( self . chunk_size ) <EOL> if not chunk : <EOL> raise StopIteration <EOL> if self . length is not None : <EOL> self . length -= len ( chunk ) <EOL> if self . length < <NUM_LIT:0> : <EOL> chunk = chunk [ : self . length ] <EOL> return chunk <EOL> def get_mimetype ( filename ) : <EOL> typ , encoding = mimetypes . guess_type ( filename ) <EOL> return typ or '<STR_LIT>' <EOL> def make_response ( filename ) : <EOL> res = Response ( content_type = get_mimetype ( filename ) , <EOL> conditional_response = True ) <EOL> res . app_iter = FileIterable ( filename ) <EOL> res . content_length = os . path . getsize ( filename ) <EOL> res . last_modified = os . path . getmtime ( filename ) <EOL> res . etag = '<STR_LIT>' % ( os . path . getmtime ( filename ) , <EOL> os . path . getsize ( filename ) , hash ( filename ) ) <EOL> return res <EOL> def file_md5 ( fpath ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> f = open ( fpath , '<STR_LIT:rb>' ) <EOL> m = hashlib . md5 ( ) <EOL> while True : <EOL> s = f . read ( <NUM_LIT> ) <EOL> if not s : <EOL> break <EOL> m . update ( s ) <EOL> return m . hexdigest ( ) <EOL> finally : <EOL> f . close ( ) <EOL> class EggServer ( object ) : <EOL> def __init__ ( self , topdir ) : <EOL> self . topdir = os . path . abspath ( topdir ) <EOL> def top_dir_response ( self , environ , start_response ) : <EOL> """<STR_LIT>""" <EOL> start_response ( '<STR_LIT>' , [ ( '<STR_LIT:Content-Type>' , '<STR_LIT>' ) ] ) <EOL> out = StringIO ( ) <EOL> out . write ( '<STR_LIT>' ) <EOL> dirs = os . listdir ( self . topdir ) <EOL> dirs . sort ( key = str . lower ) <EOL> for d in dirs : <EOL> full = os . path . join ( self . topdir , d ) <EOL> if os . path . isdir ( full ) : <EOL> out . write ( '<STR_LIT>' % ( d , d ) ) <EOL> out . write ( '<STR_LIT>' ) <EOL> return [ out . getvalue ( ) ] <EOL> def dist_dir_response ( self , environ , start_response , abspath ) : <EOL> """<STR_LIT>""" <EOL> dpath = environ [ '<STR_LIT>' ] . strip ( '<STR_LIT:/>' ) <EOL> start_response ( '<STR_LIT>' , [ ( '<STR_LIT:Content-Type>' , '<STR_LIT>' ) ] ) <EOL> out = StringIO ( ) <EOL> out . write ( '<STR_LIT>' % ( dpath , ) ) <EOL> for f in os . listdir ( abspath ) : <EOL> fpath = os . path . join ( abspath , f ) <EOL> if os . path . isfile ( fpath ) : <EOL> checksum = file_md5 ( fpath ) <EOL> lpath = os . path . join ( wsgiref . util . request_uri ( environ ) , f ) <EOL> out . write ( '<STR_LIT>' % ( lpath , checksum , f ) ) <EOL> out . write ( '<STR_LIT>' ) <EOL> return [ out . getvalue ( ) ] <EOL> def file_response ( self , environ , start_response , abspath ) : <EOL> """<STR_LIT>""" <EOL> app = FileApp ( abspath ) <EOL> return app ( environ , start_response ) <EOL> def __call__ ( self , environ , start_response ) : <EOL> global logger <EOL> if logger : <EOL> logger . info ( environ [ '<STR_LIT>' ] + '<STR_LIT>' + <EOL> wsgiref . util . request_uri ( environ ) ) <EOL> pth = environ [ '<STR_LIT>' ] <EOL> abspath = os . path . join ( self . topdir , pth . strip ( '<STR_LIT:/>' ) ) <EOL> if pth == '<STR_LIT:/>' : <EOL> return self . top_dir_response ( environ , start_response ) <EOL> elif os . path . isdir ( abspath ) : <EOL> return self . dist_dir_response ( environ , start_response , abspath ) <EOL> elif os . path . isfile ( abspath ) : <EOL> return self . file_response ( environ , start_response , abspath ) <EOL> else : <EOL> start_response ( '<STR_LIT>' , [ ( '<STR_LIT:Content-Type>' , '<STR_LIT>' ) ] ) <EOL> return [ '<STR_LIT>' + abspath + '<STR_LIT>' ] <EOL> def setup_logger ( fname ) : <EOL> logging . basicConfig ( level = logging . INFO , <EOL> format = '<STR_LIT>' , <EOL> datefmt = '<STR_LIT>' , <EOL> filename = fname , <EOL> filemode = '<STR_LIT:a>' ) <EOL> return logging . getLogger ( '<STR_LIT>' ) <EOL> def check_eggdir ( name ) : <EOL> if name is None or os . path . isdir ( name ) is False : <EOL> raise RuntimeError ( str ( name ) + '<STR_LIT>' ) <EOL> dirs = [ d for d in os . listdir ( name ) if os . path . isdir ( os . path . join ( name , d ) ) ] <EOL> for d in dirs : <EOL> for f in os . listdir ( os . path . join ( name , d ) ) : <EOL> if d != f [ <NUM_LIT:0> : len ( d ) ] : <EOL> raise RuntimeError ( '<STR_LIT>' + name + '<STR_LIT>' + <EOL> d + '<STR_LIT>' + f [ <NUM_LIT:0> : len ( d ) ] ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> parser = OptionParser ( ) <EOL> parser . add_option ( "<STR_LIT>" , action = "<STR_LIT:store>" , type = "<STR_LIT:string>" , dest = "<STR_LIT>" , <EOL> help = "<STR_LIT>" ) <EOL> parser . add_option ( "<STR_LIT>" , action = "<STR_LIT:store>" , type = "<STR_LIT:string>" , dest = "<STR_LIT>" , <EOL> help = "<STR_LIT>" + <EOL> "<STR_LIT>" + <EOL> "<STR_LIT>" + <EOL> "<STR_LIT>" , <EOL> default = "<STR_LIT:.>" ) <EOL> parser . add_option ( "<STR_LIT>" , action = "<STR_LIT:store>" , type = "<STR_LIT:int>" , dest = "<STR_LIT:port>" , default = <NUM_LIT> , <EOL> help = "<STR_LIT>" ) <EOL> ( options , args ) = parser . parse_args ( ) <EOL> eggdir = os . path . abspath ( options . eggdir ) <EOL> check_eggdir ( eggdir ) <EOL> if not os . path . isdir ( eggdir ) : <EOL> print >> sys . stderr , eggdir , '<STR_LIT>' <EOL> parser . print_help ( ) <EOL> sys . exit ( - <NUM_LIT:1> ) <EOL> if options . log : <EOL> logger = setup_logger ( options . log ) <EOL> app = EggServer ( eggdir ) <EOL> httpserver . serve ( app , host = platform . uname ( ) [ <NUM_LIT:1> ] , port = options . port ) </s>
