# Copyright (C) 2008-2010 Fog Creek Software. All rights reserved.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2, incorporated herein by reference.
import os
import re
import hashlib
import tempfile
import settings
RE_SHA1 = re.compile(r'^[0-9a-f]+$', re.IGNORECASE)
standinprefix = '.kbf'
if os.name == 'nt':
from mercurial import win32
link = win32.oslink
else:
link = os.link
def storepath(sha):
return os.path.join(settings.KILN_BFILE_STORE, sha)
def bfilecontents(sha):
return open(storepath(sha), 'rb')
def storebfile(file, sha):
path = storepath(sha)
if not os.path.exists(os.path.dirname(path)):
os.makedirs(os.path.dirname(path))
hash = hashlib.sha1()
# Write to a temporary file then if the SHA matches rename the file otherwise a user
# could give us a very large file with an incorrect SHA in order to block anyone from
# writing to that SHA while the file was being written to disk
if settings.HOSTED:
tmpdir = settings.KILN_BFILE_TMP
else:
tmpdir = settings.KILN_BFILE_STORE
fd = tempfile.NamedTemporaryFile(dir=tmpdir, delete=False)
with fd:
while True:
data = file.read(32768)
if not data:
break
fd.write(data)
hash.update(data)
if hash.hexdigest() == sha:
os.rename(fd.name, path)
return True
else:
os.unlink(fd.name)
return False
def instore(sha):
return os.path.exists(storepath(sha))
def ishash(sha):
return RE_SHA1.match(sha)
def listbfiles():
return [f for f in os.listdir(settings.KILN_BFILE_STORE) if ishash(f)]
def getbfilesize(sha):
return os.path.getsize(storepath(sha))
|
Loading...