X-Git-Url: http://git.veekun.com/zzz-floof.git/blobdiff_plain/5837da26db915faca89925c39fa83202bfb84e32..79cb1c0d3048c165fd3b9ff287ee1fbe361f904d:/floof/lib/file_storage.py?ds=sidebyside diff --git a/floof/lib/file_storage.py b/floof/lib/file_storage.py index 5595e88..b30a662 100644 --- a/floof/lib/file_storage.py +++ b/floof/lib/file_storage.py @@ -3,56 +3,62 @@ import os, shutil, tempfile, hashlib 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