--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/lib/django/core/files/base.py Wed Jan 20 00:34:04 2010 +0100
@@ -0,0 +1,134 @@
+import os
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from StringIO import StringIO
+
+from django.utils.encoding import smart_str, smart_unicode
+from django.core.files.utils import FileProxyMixin
+
+class File(FileProxyMixin):
+ DEFAULT_CHUNK_SIZE = 64 * 2**10
+
+ def __init__(self, file, name=None):
+ self.file = file
+ if name is None:
+ name = getattr(file, 'name', None)
+ self.name = name
+ self.mode = getattr(file, 'mode', None)
+
+ def __str__(self):
+ return smart_str(self.name or '')
+
+ def __unicode__(self):
+ return smart_unicode(self.name or u'')
+
+ def __repr__(self):
+ return "<%s: %s>" % (self.__class__.__name__, self or "None")
+
+ def __nonzero__(self):
+ return bool(self.name)
+
+ def __len__(self):
+ return self.size
+
+ def _get_size(self):
+ if not hasattr(self, '_size'):
+ if hasattr(self.file, 'size'):
+ self._size = self.file.size
+ elif os.path.exists(self.file.name):
+ self._size = os.path.getsize(self.file.name)
+ else:
+ raise AttributeError("Unable to determine the file's size.")
+ return self._size
+
+ def _set_size(self, size):
+ self._size = size
+
+ size = property(_get_size, _set_size)
+
+ def _get_closed(self):
+ return not self.file or self.file.closed
+ closed = property(_get_closed)
+
+ def chunks(self, chunk_size=None):
+ """
+ Read the file and yield chucks of ``chunk_size`` bytes (defaults to
+ ``UploadedFile.DEFAULT_CHUNK_SIZE``).
+ """
+ if not chunk_size:
+ chunk_size = self.DEFAULT_CHUNK_SIZE
+
+ if hasattr(self, 'seek'):
+ self.seek(0)
+ # Assume the pointer is at zero...
+ counter = self.size
+
+ while counter > 0:
+ yield self.read(chunk_size)
+ counter -= chunk_size
+
+ def multiple_chunks(self, chunk_size=None):
+ """
+ Returns ``True`` if you can expect multiple chunks.
+
+ NB: If a particular file representation is in memory, subclasses should
+ always return ``False`` -- there's no good reason to read from memory in
+ chunks.
+ """
+ if not chunk_size:
+ chunk_size = self.DEFAULT_CHUNK_SIZE
+ return self.size > chunk_size
+
+ def __iter__(self):
+ # Iterate over this file-like object by newlines
+ buffer_ = None
+ for chunk in self.chunks():
+ chunk_buffer = StringIO(chunk)
+
+ for line in chunk_buffer:
+ if buffer_:
+ line = buffer_ + line
+ buffer_ = None
+
+ # If this is the end of a line, yield
+ # otherwise, wait for the next round
+ if line[-1] in ('\n', '\r'):
+ yield line
+ else:
+ buffer_ = line
+
+ if buffer_ is not None:
+ yield buffer_
+
+ def open(self, mode=None):
+ if not self.closed:
+ self.seek(0)
+ elif self.name and os.path.exists(self.name):
+ self.file = open(self.name, mode or self.mode)
+ else:
+ raise ValueError("The file cannot be reopened.")
+
+ def close(self):
+ self.file.close()
+
+class ContentFile(File):
+ """
+ A File-like object that takes just raw content, rather than an actual file.
+ """
+ def __init__(self, content):
+ content = content or ''
+ super(ContentFile, self).__init__(StringIO(content))
+ self.size = len(content)
+
+ def __str__(self):
+ return 'Raw content'
+
+ def __nonzero__(self):
+ return True
+
+ def open(self, mode=None):
+ self.seek(0)
+
+ def close(self):
+ pass