Seite 1 von 1

Stückweise aus StringIO lesen, wie?

Verfasst: Mittwoch 22. Februar 2006, 19:49
von jens
Ich biete per CGI Dateien zum Download an... Es sind ZIP-Dateien die mit StringIO im Speicher erzeugt werden:

Code: Alles auswählen

buffer = cStringIO.StringIO()
z = zipfile.ZipFile(buffer, "w")

for file_info in files:
    z.write(file_info)
z.close()

if simulation:
    self.request.write("-"*80)
    self.request.write("\n")

buffer.seek(0,2) # Am Ende der Daten springen
buffer_len = buffer.tell() # Aktuelle Position
buffer.seek(0) # An den Anfang springen

filename = posixpath.split(self.request_path)[-1]

if not simulation:
    self.request.headers['Content-Disposition'] = 'attachment; filename="%s.zip"' % filename
    self.request.headers['Content-Length'] = '%s' % buffer_len
    self.request.headers['Content-Transfer-Encoding'] = 'binary'
    self.request.headers['Content-Type'] = 'application/octet-stream; charset=utf-8'
    self.request.write(buffer.getvalue())
Nun überlege ich ein billiges "Traffic Shaping" bzw. throttling einzubauen... Meine Idee. Ich übertrage die Daten von buffer stückweise in self.request.write() rüber und zwischendurch mache ich ein time.sleep()...

Nur, wie lese ich Stückweise aus einem StringIO herraus?

Verfasst: Mittwoch 22. Februar 2006, 20:28
von jens
Hm! Ich ideotist...

StrinIO ist ein fileobjekt, somit kann man bröckchenweise mit .read(1024) lesen und senden...

Verfasst: Mittwoch 22. Februar 2006, 21:21
von jens
Gesagt getan... Das dumme ist nur, das es nix bring, da es als CGI läuft... Der Download bedingt erst dann, wenn alle Teile durch self.request.write() durch sind...
Also kann ich so einfach keine Bandbreiten-Beschänkung einbauen :(

Mit fastCGI oder modPython müßte das aber gehen, oder?

Verfasst: Mittwoch 22. Februar 2006, 21:23
von mitsuhiko

Code: Alles auswählen

class SendDynamic(BaseApplication):
    def process_request(self):
        def send_data(self):
            from time import sleep
            for _ in xrange(20):
                sleep(0.1)
                yield "some text"
         self.request.send_response(send_data())
Sollte eigentlich auch mit cgi gehen.

Verfasst: Mittwoch 22. Februar 2006, 21:28
von jens
Jep! Das ist ja cool...

Verfasst: Donnerstag 2. März 2006, 12:51
von jens
OK, der Download funktioniert... Nun würde mich aber interessieren, ob man evtl. auch eine resume-Funktion von Download-Managern umsetzten kann?