2011-09-14 30 views
1

サーバーにファイルを作成してクライアントに提供する必要があります。そのファイルを後でサーバーから削除することをお勧めします。cherrypyでファイルを提供し、サーバーからファイルを削除するにはどうすればいいですか?

def myaction(): 
    fs = facts.generatefacts(int(low),int(high),int(amount),op) 
    filename = 'test.txt' 
    FILE = open(filename,'w') 
    FILE.writelines('my\nstuff\nhere') 
    FILE.close() 
    RETURN_FILE = open(filename,'r') 
    return serve_fileobj(RETURN_FILE,disposition='attachment', 
         content_type='.txt',name=filename) 

myaction.exposed = True 

私は好きではないこれについて、いくつかのものがあります。ここでは

は、私は現在しようとしているものです。たとえば、ファイルを2回開く必要はないと思います。私は、ファイルオブジェクトを作成することなく、レスポンスオブジェクトに直接コンテンツを書き込む方法があると期待していますが、それは今日の私の質問ではありません。

上記のコードは私が望むものを実現しますが、ファイルは残しています。レスポンスを返す前にファイルを削除すると、(もちろん)ファイルが見つかりません。

このファイルを提供したらすぐに削除する方法はありますか?

私はJavaの世界から来ているので、私は少し混乱しています。上記を改善するための他の提案は高く評価されます。

答えて

2

1)あなたは

result = serve_fileobj(RETURN_FILE,disposition='attachment', 
         content_type='.txt',name=filename) 
os.unlink(filename) 
return result 

3を試すことができます)一時フォルダにファイルを移動し、すべてのファイルを古い0.5時間

2を削除することができますが)見えるように文字列を折り返すことができたStringIOファイルオブジェクトを使用してみてくださいファイルのように。

+1

を私は第三の最良の選択肢だと思います – varela

1

下の解決策は、ファイルがcherrypyによって完全に送信されると、一時ファイル(この場合は一時ディレクトリ)をクリーンアップするために弱参照を使用します。

私は一時的なディレクトリを使用しています。これは、最終結果を送信する前に複数のファイルを作成する可能性があるためです(例えば、zip形式のExcelファイルを返すなど)良い。

import cherrypy 
from cherrypy import expose 

import zipfile 
import weakref 
import shutil 
import os 
import tempfile 

PARENT_TEMP_DATA_DIR = '/tmp/cherrypy_data_files' 

def single_file_zip(filepath): 
    'Give a filepath, creates a zip archive in the same directory, with just the single file inside' 
    filename = os.path.basename(filepath) 
    zipname = '%s.zip' % os.path.splitext(filename)[0] 
    if filename.lower() == zipname.lower(): 
     raise ValueError("Can't use .zip file as source") 
    zippath = os.path.join(os.path.dirname(filepath), zipname) 
    zf = zipfile.ZipFile(zippath, mode='w', compression=zipfile.ZIP_DEFLATED) 
    zf.write(filepath, filename) 
    zf.close() 
    return zippath 

class DataFiles(object): 
    def __init__(self): 
     self.weak_references = {} 
    def cleanup(self, wr): 
     if wr in self.weak_references: 
      filepath = self.weak_references[wr] 
      if os.path.isfile(filepath): 
       try: 
        os.remove(filepath) 
       except Exception: 
        pass 
      if os.path.isdir(filepath): 
       shutil.rmtree(filepath, ignore_errors=True) 
      self.weak_references.pop(wr) 
    @expose 
    def index(self): 
     tempdir = os.path.abspath(tempfile.mkdtemp(dir=PARENT_TEMP_DATA_DIR)) 
     txt_path = os.path.join(tempdir, 'my_data.txt') 
     with open(txt_path, 'wb') as fh: 
      fh.write('lots of data here\n') 
     zip_path = single_file_zip(txt_path) 
     os.remove(txt_path) # not strictly needed, as the cleanup routine would remove this anyway 
     result = cherrypy.lib.static.serve_download(zip_path) 

     # the weak-reference allows automatic cleanup of the temp dir once the file is served 
     wr = weakref.ref(result, self.cleanup) 
     self.weak_references[wr] = tempdir 

     return result 

if __name__=='__main__': 
    # on startup clean up any prior temporary data 
    tempdir_parent = PARENT_TEMP_DATA_DIR 
    print 'Clearing %s' % tempdir_parent 
    if not os.path.exists(tempdir_parent): 
     os.mkdir(tempdir_parent) 
    for filename in os.listdir(tempdir_parent): 
     filepath = os.path.join(tempdir_parent, filename) 
     if os.path.isfile(filepath): 
      print 'Deleting file %s' % filepath 
      os.remove(filepath) 
     if os.path.isdir(filepath): 
      print 'Removing directory %s and all contents' % filepath 
      shutil.rmtree(filepath, ignore_errors=True) 

    # start CherryPy 
    cherrypy.quickstart(DataFiles()) 
0

これが私の仕事:

class Handler: 

    ... 

    def download_complete(self) 
     os.unlink(cherrypy.request.zipFileName) 

    def download(self, path) 
     zipFileName = createZip(path) 
     cherrypy.request.zipFileName = zipFileName 
     cherrypy.request.hooks.attach('on_end_request', self.download_complete) 
     return cherrypy.lib.static.serve_download(zipFileName) 
関連する問題