[CalendarServer-changes] [9148] CalendarServer/trunk/txdav/caldav/datastore/sql.py

source_changes at macosforge.org source_changes at macosforge.org
Wed Apr 18 13:58:45 PDT 2012


Revision: 9148
          http://trac.macosforge.org/projects/calendarserver/changeset/9148
Author:   sagen at apple.com
Date:     2012-04-18 13:58:45 -0700 (Wed, 18 Apr 2012)
Log Message:
-----------
Stream attachments straight to disk during PUT

Modified Paths:
--------------
    CalendarServer/trunk/txdav/caldav/datastore/sql.py

Modified: CalendarServer/trunk/txdav/caldav/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/sql.py	2012-04-18 15:07:01 UTC (rev 9147)
+++ CalendarServer/trunk/txdav/caldav/datastore/sql.py	2012-04-18 20:58:45 UTC (rev 9148)
@@ -29,6 +29,7 @@
 from twext.python.vcomponent import VComponent
 from txdav.xml.rfc2518 import ResourceType
 from twext.web2.http_headers import MimeType, generateContentType
+from twext.python.filepath import CachingFilePath
 
 from twisted.internet.defer import inlineCallbacks, returnValue
 from twisted.internet.error import ConnectionLost
@@ -82,6 +83,8 @@
 
 from zope.interface.declarations import implements
 
+import os
+import tempfile
 import uuid
 
 class CalendarHome(CommonHome):
@@ -1165,14 +1168,34 @@
 
 class AttachmentStorageTransport(StorageTransportBase):
 
+    _TEMPORARY_UPLOADS_DIRECTORY = "Temporary"
+
     def __init__(self, attachment, contentType, creating=False):
         super(AttachmentStorageTransport, self).__init__(
             attachment, contentType)
-        self._buf = ''
+
+        fileDescriptor, fileName = self._temporaryFile()
+        # Wrap the file descriptor in a file object we can write to
+        self._file = os.fdopen(fileDescriptor, "w")
+        self._path = CachingFilePath(fileName)
         self._hash = hashlib.md5()
         self._creating = creating
 
 
+    def _temporaryFile(self):
+        """
+        Returns a (file descriptor, absolute path) tuple for a temporary file within
+        the Attachments/Temporary directory (creating the Temporary subdirectory
+        if it doesn't exist).  It is the caller's responsibility to remove the
+        file.
+        """
+        attachmentRoot = self._txn._store.attachmentsPath
+        tempUploadsPath = attachmentRoot.child(self._TEMPORARY_UPLOADS_DIRECTORY)
+        if not tempUploadsPath.exists():
+            tempUploadsPath.createDirectory()
+        return tempfile.mkstemp(dir=tempUploadsPath.path)
+
+
     @property
     def _txn(self):
         return self._attachment._txn
@@ -1181,7 +1204,7 @@
     def write(self, data):
         if isinstance(data, buffer):
             data = str(data)
-        self._buf += data
+        self._file.write(data)
         self._hash.update(data)
 
 
@@ -1200,18 +1223,20 @@
                     self._attachment._ownerHomeID))
 
         oldSize = self._attachment.size()
-
+        newSize = self._file.tell()
+        self._file.close()
         allowed = home.quotaAllowedBytes()
         if allowed is not None and allowed < ((yield home.quotaUsedBytes())
-                                              + (len(self._buf) - oldSize)):
+                                              + (newSize - oldSize)):
+            self._path.remove()
             if self._creating:
                 yield self._attachment._internalRemove()
             raise QuotaExceeded()
 
-        self._attachment._path.setContent(self._buf)
+        self._path.moveTo(self._attachment._path)
         self._attachment._contentType = self._contentType
         self._attachment._md5 = self._hash.hexdigest()
-        self._attachment._size = len(self._buf)
+        self._attachment._size = newSize
         att = schema.ATTACHMENT
         self._attachment._created, self._attachment._modified = map(
             sqltime,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120418/7ae81a96/attachment-0001.html>


More information about the calendarserver-changes mailing list