1

私はHTML WYSIWYGエディターに取り組んでおり、現在、ユーザーがダウンロードボタンを押してテーマのzipファイルをダウンロードできる「ダウンロード」機能に取り組んでいます。この機能を実現するために Python CGI スクリプトを使用しています。現在、私のスクリプトは zip ファイルを作成し、それをダウンロードするようユーザーに促しますが、zip ファイルを解凍しようとすると、拡張子が「.cpgz」の別の zip ファイルしか作成されません。私のスクリプトが zip を適切に作成しなかったと思います。

「zipfile」モジュールを使用してディスクではなくメモリ内に zipfile オブジェクトを作成し、「StringIO」モジュールを使用してメモリ内にファイルのようなオブジェクトを作成し、「cgi」モジュールを使用して Ajax リクエストから POST データを受け取ります。

私の問題は、for ループにあります。「zf」zip ファイルは、os.walk() に渡した「layoutDir」パラメーターからファイルとサブディレクトリを追加していません。スクリプトはブラウザーに 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()

更新 1: コードに含まれていた無関係なものをいくつか削除しました。また、「absfn」と「adsfn」のタイプミスを修正します。上記のコードは、ローカルのコード エディターにあるものを正確に表しています。作成したzipファイルを解凍できないという同じ問題がまだあります。

更新 2: 私のコンピューターの「マーケティング」ディレクトリは次のようになります。

|---- Marketing
      |---- css
      |    |---- default.css
      | 
      |---- img
      |
      |---- index.html
4

1 に答える 1

0

これが実際のコードである場合、問題は単純なタイプミスです。

zf.write(adsfn, relfn)

という名前の変数はありません。 という名前の変数がありadsfnますabsfn。したがって、これにより a が発生NameErrorし、何も返されません。

私がそれを修正した場合は、このコードをlayoutDir何らかの階層を持つ適切な相対パスに設定して実行し、結果のメモリ内 zip ファイルを次のようにディスクに保存します。

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

…その後、すべてのファイルが適切に保存された zip ファイルが完成します。つまり、まったく問題はありません。

したがって、そのタイプミスが問題ではない場合、問題が何であれ、投稿したコードと私たちが見ることができない実際のコードとの間の他の違いのように見えます.


あなたの実際の問題は、実際のコードで、のような絶対または相対 URL を使用しようとしているようhttp://localhost:8888/path-to/MarketingですlayoutDir。URL とパスは同じものではありません。これをパス 1 として使用しようとすると、実質的に と同じになり./http:/localhost:8888/path-to-Marketingます。ほとんどhttp:の場合、現在の作業ディレクトリに名前の付いたディレクトリがないため、os.walk何も生成されず、空の zip ファイルが作成されることになります。

追加しようとしているファイルが実際に何らかの (相対または絶対) パスで利用できる場合は、URL の代わりにそのパスを使用すると、問題は解決します。

それらが HTTP 経由でしか利用できない場合、あなたがしようとしていることは不可能です。HTTP URL の「サブディレクトリ」をたどる方法はありません。その概念は意味さえありません。もちろん、多くの場合、Web サーバーは URL パスの一部を何らかのファイルシステム パスにマップし、そのファイルシステムを間接的にナビゲートする何らかの方法を提供します (たとえば、リンクでいっぱいの index.html ページを自動生成するオプションを用意するなど)。それを利用するには、問題のサーバーがその情報をどのように公開しているかを正確に把握し、それを利用するためのスクレイピング コードを記述する必要があります。そして、すべてのリンクを取得した後でも URL を に渡すことはできず、ファイルzipfile.writeのみを渡すことができます。つまり、各 URL をダウンロードする必要があります (たとえば、メモリに読み込んでから結果を取得するなど)。writestr

于 2014-01-06T05:51:49.017 に答える