chunk_size = 1024*1024 # TODO: is this a good chunk size?
+from pylons import config
+
"""
Notes:
-# Here's one way to move stuff...
-shutil.copyfileobj(temp.file, dest_file)
-
-# we should probably store the basename of the original filename in the database somewhere
-temp_base = os.path.basename(temp.filename)
-
# You can get a mime type like so:
from mimetypes import guess_type
guess_type(temp.filename)[0]
"""
+def get_path(space, hash):
+ return "/" + os.path.join( space, hash[:2], hash[2:] )
+
+
+def save_file(space, fileobj, hash=None):
+ """Saves the contents of fileobj to the given storage space.
+
+ If a hash is not provided, the SHA-1 sum of the file will be computed and
+ that will be used. The ideal scenario here is to let the hash of the
+ original file be computed automatically, then create thumbnails et al. with
+ the same hash in a different space.
+
+ Returns the hashsum.
+ """
+ dest_root = os.path.join( config['app_conf']['static_root'], space )
+
+ # The incoming fileobj could be a tempfile that's already been unlinked --
+ # and probably is, as it's coming from a Pylons upload object. Thus we
+ # have to copy the data rather than the file, and we may have to read the
+ # file anyway to hash it, so do both at the same time.
+
+ # Need a named temporary file to write to; it gets renamed once the hash is
+ # computed
+ temp_fd, temp_path = tempfile.mkstemp()
+ temp_file = os.fdopen(temp_fd, "wb")
-def save_file(dest_root, temp):
- # we don't know where we're going to save this stuff yet,
- # so I guess we'll write it to another tempfile. One we know the path of.
- # I'm assuming the tempfile we get from pylons is set to delete itself
- # when it closes, and has no visible path. Maybe I'm wrong?
- intermediate_file_descriptor, intermediate_path = tempfile.mkstemp()
-
- # that function gives me an integer file descriptor for some reason.
- intermediate_file = os.fdopen(intermediate_file_descriptor, "wb")
-
sha1 = hashlib.sha1()
- while 1:
- data = temp.file.read(chunk_size)
+ while True:
+ data = fileobj.read(chunk_size)
if not data:
break
- sha1.update(data)
- intermediate_file.write(data)
-
- temp.file.close()
- intermediate_file.close()
- hash = sha1.hexdigest()
- # git convention: first two characters are the directory
- dest_dir = os.path.join( dest_root, hash[:2] )
- dest_path = os.path.join( dest_dir, hash[2:] )
+ if not hash:
+ sha1.update(data)
+ temp_file.write(data)
- makedirs(dest_dir)
- os.rename(intermediate_path, dest_path)
-
- return hash
+ temp_file.close()
+ if not hash:
+ hash = sha1.hexdigest()
+ # Git convention: first two characters are the directory
+ dest_dir = os.path.join(dest_root, hash[:2])
+ dest_path = os.path.join(dest_dir, hash[2:])
+ if not os.path.exists(dest_dir):
+ os.makedirs(dest_dir)
+ print dest_path
+ shutil.move(temp_path, dest_path)
-def makedirs(dir):
- try:
- os.makedirs(dir)
- except OSError:
- pass
-
\ No newline at end of file
+ return hash