1 from paste.progress import *
   2 import time
   3 
   4 upload_page = '''
   5 <html>
   6     <head>
   7         <script type="text/javascript">
   8             // Tested with Opera 9.01, Firefox beta 2 on Linux, should
   9             // work with IE 6+
  10 
  11             poller = false;
  12             busy = false;
  13             http = false;
  14 
  15             function getstats() {
  16                 // Get our XMLHttpRequest object and submit request for stats
  17                 if(!busy){
  18                     http = false;
  19                     if(window.XMLHttpRequest) {
  20                         http = new XMLHttpRequest();
  21                     }
  22                     else if(window.ActiveXObject) {
  23                         try {
  24                             http = new ActiveXObject("Msxml2.XMLHTTP");
  25                         } catch (e) {
  26                             try {
  27                                 http = new ActiveXObject("Microsoft.XMLHTTP");
  28                             } catch (e) {}
  29                         }
  30                     }
  31                     if(!http) {
  32                         alert("We're uploading the file, but your browser isn't letting us use AJAX.");
  33                         document.getElementById('upload_stat').innerHTML='Not available.';
  34                         return false;
  35                     }
  36 
  37                     busy = true;
  38                     http.onreadystatechange = update_stat;
  39                     http.open("GET", "/report", true);
  40                     http.send(null);
  41                 }
  42             }
  43 
  44             function update_stat(){
  45                 var result;
  46                 // Handles the request for stats.
  47                 if(http.readyState == 4){
  48                     if(http.status != 200){
  49                        document.getElementById('upload_stat').innerHTML='Stats unavailable. Wait for it.';
  50                         clearInterval(poller);
  51                     }else{
  52                         result = eval(http.responseText)
  53                         var current = result[result.length-1]
  54                         received = current.bytes_received
  55                         size = current.content_length
  56                         document.getElementById('upload_stat').innerHTML=100*received/size + "%";
  57                         if(http.responseText.indexOf('No active transfers!') != -1){
  58                             clearInterval(poller);
  59                         }
  60                     }
  61                 }
  62                 busy = false;
  63             }
  64             function start_stat(){
  65                 // Hides our upload form and displays our stats element.
  66                 poller = setInterval("getstats()", 2000);
  67                 document.getElementById('upload_stat').style.display = 'block';
  68                 document.getElementById('upload_form').style.display = 'none';
  69             }
  70         </script>
  71     </head>
  72     <body>
  73         <!-- Our form will call the polling system for stats when it's submitted, as well as start the uploading of the file. -->
  74         <h1>File upload with progress bar</h1>
  75         <p>This is a sample of how to use UploadFilter, including how to keep track of
  76         files as they're being uploaded to a cherrypy server...</p>
  77         Choose your files:<br/>
  78         <form class="upload_form" action="" method="post" enctype="multipart/form-data" onsubmit="start_stat()">
  79             <input type="file" name="myFile"/>
  80             <input type="submit" value="Upload File"/>
  81         </form>
  82         <form class="upload_form" action="" method="post" enctype="multipart/form-data" onsubmit="start_stat()">
  83             <input type="file" name="myFile"/>
  84             <input type="submit" value="Upload File"/>
  85         </form>
  86         <!-- This is where we'll be putting our statistics. It's hidden to start off. -->
  87         <div id="upload_stat" style="display:none;">Connecting...</div>
  88     </body>
  89 </html>'''
  90 
  91 def FileUploadApp(environ, start_response):
  92     total = environ.get('CONTENT_LENGTH')
  93     if total:
  94         body = '''
  95         <html><head><title>Upload Succed!</title></head>
  96         <body><h5>%s bytes upload succed!</h5></body></html>
  97         ''' % total
  98     else:
  99         body = upload_page
 100 
 101     start_response('200 OK', [('Content-Type','text/html'),
 102                               ('Content-Length',len(body))])
 103     return [body]
 104 
 105 class FileUploader(object):
 106     def __init__(self, app):
 107         self.chunk_size = 4096
 108         self.delay = 1
 109         self.progress = True
 110         self.app = app
 111     def __call__(self, environ, start_response):
 112         size = 0
 113         total  = environ.get('CONTENT_LENGTH')
 114         if total:
 115             remaining = int(total)
 116             while remaining > 0:
 117                 if self.progress:
 118                     print "%s of %s remaining" % (remaining, total)
 119                 if remaining > 4096:
 120                     chunk = environ['wsgi.input'].read(4096)
 121                 else:
 122                     chunk = environ['wsgi.input'].read(remaining)
 123                 if not chunk:
 124                     break
 125                 size += len(chunk)
 126                 remaining -= len(chunk)
 127                 if self.delay:
 128                     time.sleep(self.delay)
 129         print "bingles"
 130         return self.app(environ, start_response)
 131 
 132 if __name__ == '__main__':
 133     from paste.httpserver import serve
 134     from paste.urlmap import URLMap
 135     from paste.auth.basic import AuthBasicHandler
 136     realm = 'Test Realm'
 137     def authfunc(environ, username, password):
 138         return username == password
 139 
 140     map = URLMap({})
 141     ups = UploadProgressMonitor(map, threshold=1024, timeout=0)
 142     map['/upload'] = FileUploader(FileUploadApp)
 143     map['/report'] = UploadProgressReporter(ups)
 144     serve(AuthBasicHandler(ups, realm, authfunc))