2014-01-06 4 views
1

Я работаю над редактором HTML WYSIWYG, и сейчас я работаю над функцией «Загрузить», где пользователь может нажать кнопку «Загрузить», чтобы загрузить zip-файл своей темы. Я использую скрипт CGI Python для достижения этой функции. В настоящее время мой скрипт создает zip-файл и предлагает пользователю загрузить его, но когда я пытаюсь распаковать zip-файл, он создает только другой zip-файл с расширением «.cpgz». Я считаю, что мой скрипт не создавал почтовый индекс.Создать Zipfile в Python в памяти на веб-сервере

Я использую модуль zipfile для создания zipfile-объекта в памяти вместо Disk, модуля StringIO для создания файлового объекта в памяти и модуля cgi для приема данных POST от Ajax запрос.

Моя проблема в моей петле. Zip-файл zf не добавляет файлы и подкаталоги из параметра layoutDir, который я передал в os.walk(). Сценарий предложит браузеру загрузить zip-файл, но я не могу его распаковать.

#!/usr/bin/python 

import sys 
import os 
import zipfile 
import StringIO 
import cgitb 

cgitb.enable() 

layoutDir = 'http://localhost:8888/funWYSIWYG/public/views/layouts/Marketing' 

tmpZip = StringIO.StringIO() 
zf = zipfile.ZipFile(tmpZip, 'w', zipfile.ZIP_DEFLATED) 

for root, dirs, files in os.walk(layoutDir): 
    for name in files: 
     absfn = os.path.join(root, name) 
     relfn = absfn[len(layoutDir) + len(os.sep):] 
     zf.write(absfn, relfn) 

zf.close() 

sys.stdout.write("Content-Type: application/octet-stream\r\n") 
sys.stdout.write("Content-Disposition: attachment; filename=\"funWYSIWYG-Marketing.zip\"\r\n\r\n") 

sys.stdout.write(tmpZip.getvalue()) 

# Close opened file 
tmpZip.close() 

UPDATE 1: Я избавилась от некоторых неактуальных вещей, который был в моем коде. Я также исправляю опечатку с помощью «absfn» и «adsfn». Теперь приведенный выше код представляет собой то, что я имею в своем локальном редакторе кода. У меня по-прежнему возникает одна и та же проблема: не удается распаковать zip-файл, который был создан.

ОБНОВЛЕНИЕ 2: Вот как выглядит каталог «Маркетинг» на моем компьютере.

|---- Marketing 
     |---- css 
     | |---- default.css 
     | 
     |---- img 
     | 
     |---- index.html 
+0

В качестве дополнительной заметки ['os.path.relpath'] (http://docs.python.org/2/library/os.path.html#os.path.relpath) намного лучший способ получить относительный путь, чем пытаться выработать длину префикса и отрезать его вручную. – abarnert

+0

Кроме того, '\ r \ n \ n' почти никогда не то, что вы хотите в любом контексте. Если вам нужно отправить CRLF, вам нужно '\ r \ n \ r \ n'. Если вы этого не сделаете, вы просто хотите '\ n \ n'. Я не могу придумать ни одного случая, когда вам нужны CRLF и некоторые простые LF. – abarnert

+0

И, наконец, это ваш фактический код? Если это так, ваша проблема - простая опечатка: 'adsfn' поднимет' NameError', потому что такой переменной нет. Если нет, то, пожалуйста, дайте нам [SSCCE] (http://sscce.org), который фактически запускает и демонстрирует проблему. (Еще одна его часть - это SSCCE, которая удаляет ненужные вещи. Если вы не считаете, что материал CGI связан с проблемой, дайте нам более простую программу, которая просто создает zip-файл и, скажем, сохраняет его в локальном файле.) – abarnert

ответ

0

Если это ваш фактический код, ваша проблема просто опечатка:

zf.write(adsfn, relfn) 

Вы не имеют переменную с именем adsfn, вы один с именем absfn. Таким образом, это поднимет NameError и ничего не вернет.

Если это исправить, а затем запустить этот код с layoutDir набором для разумного относительного пути с какой-то иерархии в нем, и сохранить полученный в памяти ZipFile на диск, как это:

with open('foo.zip', 'wb') as f: 
    f.write(tmpZip.getvalue()) 

... то в итоге я получаю zip-файл со всеми файлами, хранящимися в нем, что означает, что проблем нет.

Итак, если эта опечатка не ваша проблема, то что бы ни было is, ваша проблема, похоже, отличается от кода, который вы опубликовали, и фактического кода, который мы не можем видеть.


Похоже, ваш актуальной проблемой является то, что в вашем реальном коде, вы пытаетесь использовать абсолютный или относительный URL , как http://localhost:8888/path-to/Marketing, как layoutDir. URL-адреса и пути - это не одно и то же. Если вы попытаетесь использовать это как один путь, он будет фактически таким же, как ./http:/localhost:8888/path-to-Marketing. У вас почти наверняка нет каталога с именем http: в текущем рабочем каталоге, поэтому os.walk ничего не даст, а это значит, что вы создадите пустой почтовый файл.

Если файлы, которые вы пытаетесь добавить, действительно доступны на некотором (относительном или абсолютном) пути, используйте этот путь вместо URL-адреса, и ваша проблема исчезнет.

Если они доступны только через HTTP, то то, что вы пытаетесь сделать, невозможно; нет никакого способа передвижения «подкаталогов» URL-адреса HTTP; концепция не имеет смысла. Во многих случаях, конечно, веб-серверы сопоставляют части пути URL-адреса к некоторому пути файловой системы и предоставляют некоторый способ косвенной навигации по этой файловой системе (например, имея возможность автоматически генерировать страницу index.html, полную ссылок), но чтобы воспользоваться тем, что вам нужно точно знать, как данный сервер подвергается этой информации, а затем писать код очистки, чтобы воспользоваться этим. И тогда, даже если у вас есть все ссылки, вы не можете передать URL-адрес zipfile.write, только файл. Это означает, что вам необходимо загрузить каждый URL (например, прочитать его в памяти, а затем writestr результат).

+0

Не могли бы вы показать мне, какой относительный путь вы использовали? Я добавил код, который вы только что написал в конец моего скрипта, но он создал zip-файл на сервере, который я все еще не могу распаковать. – Rashad

+0

Относительный путь, который я использовал, был 'foo'. Я создал директорию с именем 'foo' рядом с скриптом, добавил в нее каталог с именем' bar' и добавил текстовые файлы с 1 строкой с именем 'spam' и' eggs' как для 'foo', так и' foo/bar'. Получаемый 'foo.zip' - это zip-файл, который воспроизводит эту структуру (при расширении с помощью Python или стандартной InfoZip' unzip' 5.52). – abarnert

+0

Как я экспериментировал с вашим методом, и я думаю, что я обнаружил, что представляет собой реальная проблема. Я изменил layoutDir на относительный путь, отражающий то, что находится на моем локальном диске, и скрипт работает. Он создает zip-файл содержимого в папке «Маркетинг», и я могу его распаковать. Тем не менее, я пытаюсь подражать этому же действию на веб-сервере. Когда я меняю layoutDir на относительный путь на моем веб-сервере или на абсолютный путь на 'http: // localhost: 8888/path-to/Marketing', он не работает. – Rashad

Смежные вопросы