file.py 5.08 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
##############################################################################
#
# Copyright (c) 2009-2010 Nexedi SA and Contributors. All Rights Reserved.
#                    Gabriel M. Monnerat <gabriel@tiolive.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
13 14 15
# This program is free software: you can Use, Study, Modify and Redistribute
# it under the terms of the GNU General Public License version 3, or (at your
# option) any later version, as published by the Free Software Foundation.
16
#
17 18 19 20 21
# You can also Link and Combine this program with other software covered by
# the terms of any of the Free Software licenses or any of the Open Source
# Initiative approved licenses and Convey the resulting work. Corresponding
# source of such a combination shall include the source code for all other
# software used.
22
#
23 24 25 26 27
# This program is distributed WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options.
28 29 30 31 32 33 34 35 36 37
#
##############################################################################

import mimetypes
import tempfile
from os.path import join, exists, curdir, abspath
from os import listdir, remove, chdir
from zope.interface import implements
from zipfile import ZipFile, is_zipfile
from shutil import rmtree
38
from cloudooo.interfaces.file import IFile
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144


class File(object):
  """File is used to manipulate one temporary file
  stored into the filesystem.
  """
  implements(IFile)

  def __init__(self, base_folder_url, data, source_format):
    """Create an file into file system and store the URL.
    Keyword arguments:
    base_folder_url -- Full path to create a temporary folder
    data -- Content of the document
    source_format -- Document Extension
    """
    self.base_folder_url = base_folder_url
    self.directory_name = self._createDirectory()
    self.original_data = data
    self.source_format = source_format
    self.url = self.load()

  def _createDirectory(self):
     return tempfile.mkdtemp(dir=self.base_folder_url)

  def load(self):
    """Creates one Temporary Document and write data into it.
    Return the url for the document.
    """
    # creates only the url of the file.
    file_path = tempfile.mktemp(suffix=".%s" % self.source_format,
                                dir=self.directory_name)
    # stores the data in temporary file
    open(file_path, 'wb').write(self.original_data)
    # If is a zipfile is need extract all files from whitin the compressed file
    if is_zipfile(file_path):
      zipfile = ZipFile(file_path)
      zip_filename_list = zipfile.namelist()
      if 'mimetype' not in zip_filename_list and \
          '[Content_Types].xml' not in zip_filename_list:
        zipfile_path = file_path
        zipfile.extractall(path=self.directory_name)
        zipfile.close()
        filename_list = listdir(self.directory_name)
        if 'index.html' in filename_list:
          file_path = join(self.directory_name, 'index.html')
        else:
          mimetype_list = ['text/html', 'application/xhtml+xml']
          for filename in filename_list:
            if mimetypes.guess_type(filename)[0] in mimetype_list:
              file_path = join(self.directory_name, filename)
              break
        if zipfile_path != file_path:
          remove(zipfile_path)
    return file_path

  def getContent(self, zip=False):
    """Open the file and returns the content.
    Keyword Arguments:
    zip -- Boolean attribute. If True"""
    if zip:
      current_dir_url = abspath(curdir)
      chdir(self.directory_name)
      zip_path = tempfile.mktemp(suffix=".zip", dir=self.directory_name)
      file_list = listdir(self.directory_name)
      zipfile = ZipFile(zip_path, 'w')
      try:
        for file in iter(file_list):
          zipfile.write(file)
      finally:
        zipfile.close()
      opened_zip = open(zip_path, 'r').read()
      remove(zip_path)
      chdir(current_dir_url)
      return opened_zip
    else:
      return open(self.url, 'r').read()

  def getUrl(self):
    """Returns full path."""
    return self.url

  def restoreOriginal(self):
    """Remake the document with the original document"""
    self.trash()
    self.directory_name = self._createDirectory()
    self.url = self.load()

  def reload(self, url=None):
    """If the first document is temporary and another document is created. Use
    reload to load the new document.

    Keyword Arguments:
    url -- Full path of the new document(default None)
    """
    if self.url != url and url is not None:
      remove(self.url)
      self.url = url

  def trash(self):
    """Remove the file in file system."""
    if exists(self.directory_name):
      rmtree(self.directory_name)
      self.url = None

  def __del__(self):
    self.trash()