Files
tradon/filestore.py
2025-12-26 13:11:43 +00:00

68 lines
2.0 KiB
Python
Executable File

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import hashlib
import os
from trytond.config import config
from trytond.tools import resolve
__all__ = ['filestore']
class FileStore(object):
def get(self, id, prefix=''):
filename = self._filename(id, prefix)
with open(filename, 'rb') as fp:
return fp.read()
def getmany(self, ids, prefix=''):
return [self.get(id, prefix) for id in ids]
def size(self, id, prefix=''):
filename = self._filename(id, prefix)
statinfo = os.stat(filename)
return statinfo.st_size
def sizemany(self, ids, prefix=''):
return [self.size(id, prefix) for id in ids]
def set(self, data, prefix=''):
id = self._id(data)
filename = self._filename(id, prefix)
dirname = os.path.dirname(filename)
os.makedirs(dirname, mode=0o770, exist_ok=True)
collision = 0
while True:
basename = os.path.basename(filename)
if os.path.exists(filename):
if data != self.get(basename, prefix):
collision += 1
filename = self._filename(
'%s-%s' % (id, collision), prefix)
continue
else:
with open(filename, 'wb')as fp:
fp.write(data)
return basename
def setmany(self, data, prefix=''):
return [self.set(d, prefix) for d in data]
def _filename(self, id, prefix):
path = os.path.normpath(config.get('database', 'path'))
filename = os.path.join(path, prefix, id[0:2], id[2:4], id)
filename = os.path.normpath(filename)
if not filename.startswith(path):
raise ValueError('Bad prefix')
return filename
def _id(self, data):
return hashlib.md5(data).hexdigest()
if config.get('database', 'class'):
FileStore = resolve(config.get('database', 'class')) # noqa: F811
filestore = FileStore()