lbry-sdk/lbrynet/blob/creator.py

54 lines
1.8 KiB
Python
Raw Normal View History

2017-09-13 21:46:39 +02:00
import os
import logging
from io import BytesIO
from twisted.internet import defer
from twisted.web.client import FileBodyProducer
from lbrynet.core.cryptoutils import get_lbry_hash_obj
log = logging.getLogger(__name__)
class BlobFileCreator:
2017-09-13 21:46:39 +02:00
"""
This class is used to create blobs on the local filesystem
when we do not know the blob hash beforehand (i.e, when creating
a new stream)
"""
def __init__(self, blob_dir):
self.blob_dir = blob_dir
self.buffer = BytesIO()
self._is_open = True
self._hashsum = get_lbry_hash_obj()
self.len_so_far = 0
self.blob_hash = None
self.length = None
@defer.inlineCallbacks
def close(self):
self.length = self.len_so_far
self.blob_hash = self._hashsum.hexdigest()
if self.blob_hash and self._is_open and self.length > 0:
# do not save 0 length files (empty tail blob in streams)
# or if its been closed already
2017-09-13 21:46:39 +02:00
self.buffer.seek(0)
out_path = os.path.join(self.blob_dir, self.blob_hash)
producer = FileBodyProducer(self.buffer)
yield producer.startProducing(open(out_path, 'wb'))
self._is_open = False
if self.length > 0:
defer.returnValue(self.blob_hash)
else:
# 0 length files (empty tail blob in streams )
# must return None as their blob_hash for
# it to be saved properly by EncryptedFileMetadataManagers
defer.returnValue(None)
2017-09-13 21:46:39 +02:00
def write(self, data):
if not self._is_open:
raise IOError
2018-07-13 06:21:45 +02:00
if not isinstance(data, bytes):
data = data.encode()
2017-09-13 21:46:39 +02:00
self._hashsum.update(data)
self.len_so_far += len(data)
self.buffer.write(data)