X-Git-Url: http://git.veekun.com/zzz-floof.git/blobdiff_plain/17b3828d837e1ccea92e08bd8c2ae84089add658..d2cfab09f98980d5c1d433a9e75eb65e0b13b0aa:/floof/lib/file_storage.py?ds=sidebyside diff --git a/floof/lib/file_storage.py b/floof/lib/file_storage.py index 4469394..b30a662 100644 --- a/floof/lib/file_storage.py +++ b/floof/lib/file_storage.py @@ -7,12 +7,6 @@ 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] @@ -20,47 +14,51 @@ guess_type(temp.filename)[0] def get_path(space, hash): return "/" + os.path.join( space, hash[:2], hash[2:] ) - -def save_file(space, temp): - + +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 ) - - # 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) - if not data: - break - sha1.update(data) - intermediate_file.write(data) - temp.file.close() - intermediate_file.close() - hash = sha1.hexdigest() + # 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. - # 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:] ) + # 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") - makedirs(dest_dir) - shutil.move(intermediate_path, dest_path) + sha1 = hashlib.sha1() + while True: + data = fileobj.read(chunk_size) + if not data: + break - return hash + if not hash: + sha1.update(data) + temp_file.write(data) + 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:]) -def makedirs(dir): - try: - os.makedirs(dir) - except OSError: - pass + if not os.path.exists(dest_dir): + os.makedirs(dest_dir) + print dest_path + shutil.move(temp_path, dest_path) + return hash