Compare commits
2 commits
master
...
managed-st
Author | SHA1 | Date | |
---|---|---|---|
|
69e7566eaa | ||
|
399ac561c4 |
2 changed files with 74 additions and 58 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
import os
|
||||||
import logging
|
import logging
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from binascii import hexlify, unhexlify
|
from binascii import hexlify, unhexlify
|
||||||
|
@ -93,10 +94,16 @@ def encode_file_doc():
|
||||||
'txid': '(str) None if claim is not found else the transaction id',
|
'txid': '(str) None if claim is not found else the transaction id',
|
||||||
'nout': '(int) None if claim is not found else the transaction output index',
|
'nout': '(int) None if claim is not found else the transaction output index',
|
||||||
'outpoint': '(str) None if claim is not found else the tx and output',
|
'outpoint': '(str) None if claim is not found else the tx and output',
|
||||||
|
'claim': '(Claim) None if claim is not found',
|
||||||
'metadata': '(dict) None if claim is not found else the claim metadata',
|
'metadata': '(dict) None if claim is not found else the claim metadata',
|
||||||
|
'protobuf': '(str) hex encoded Stream protobuf',
|
||||||
'channel_claim_id': '(str) None if claim is not found or not signed',
|
'channel_claim_id': '(str) None if claim is not found or not signed',
|
||||||
'channel_name': '(str) None if claim is not found or not signed',
|
'channel_name': '(str) None if claim is not found or not signed',
|
||||||
'claim_name': '(str) None if claim is not found else the claim name'
|
'claim_name': '(str) None if claim is not found else the claim name',
|
||||||
|
'content_fee': '(Transaction) None if content claim did not have a fee',
|
||||||
|
'height': '(int) height of the claim',
|
||||||
|
'confirmations': '(int) number of blocks since the claim was confirmed',
|
||||||
|
'timestamp': '(int) timestamp of the block containing the claim'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -218,15 +225,69 @@ class JSONResponseEncoder(JSONEncoder):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def encode_file(self, managed_stream):
|
def encode_file(self, managed_stream):
|
||||||
file = managed_stream.as_dict()
|
full_path = managed_stream.full_path
|
||||||
tx_height = managed_stream.stream_claim_info.height
|
file_name = managed_stream.file_name
|
||||||
best_height = self.ledger.headers.height
|
download_directory = managed_stream.download_directory
|
||||||
file.update({
|
if managed_stream.full_path and managed_stream.output_file_exists:
|
||||||
|
if managed_stream.written_bytes:
|
||||||
|
written_bytes = managed_stream.written_bytes
|
||||||
|
else:
|
||||||
|
written_bytes = os.stat(managed_stream.full_path).st_size
|
||||||
|
else:
|
||||||
|
full_path = None
|
||||||
|
file_name = None
|
||||||
|
download_directory = None
|
||||||
|
written_bytes = None
|
||||||
|
|
||||||
|
if managed_stream.stream_claim_info:
|
||||||
|
tx_height = managed_stream.stream_claim_info.height
|
||||||
|
best_height = self.ledger.headers.height
|
||||||
|
timestamp = self.ledger.headers[tx_height]['timestamp'] if tx_height > 0 else None
|
||||||
|
confirmations = None if not tx_height else ((best_height + 1) - tx_height if tx_height > 0 else tx_height)
|
||||||
|
else:
|
||||||
|
tx_height = None
|
||||||
|
timestamp = None
|
||||||
|
confirmations = None
|
||||||
|
return {
|
||||||
|
'streaming_url': f"http://{managed_stream.config.streaming_host}:{managed_stream.config.streaming_port}"
|
||||||
|
f"/stream/{managed_stream.sd_hash}",
|
||||||
|
'completed': (managed_stream.output_file_exists and (managed_stream.status in ('stopped', 'finished'))
|
||||||
|
or not managed_stream.saving.is_set()) or all(
|
||||||
|
managed_stream.blob_manager.is_blob_verified(b.blob_hash)
|
||||||
|
for b in managed_stream.descriptor.blobs[:-1]),
|
||||||
|
'file_name': file_name,
|
||||||
|
'download_directory': download_directory,
|
||||||
|
'points_paid': 0.0,
|
||||||
|
'stopped': not managed_stream.running,
|
||||||
|
'stream_hash': managed_stream.stream_hash,
|
||||||
|
'stream_name': managed_stream.descriptor.stream_name,
|
||||||
|
'suggested_file_name': managed_stream.descriptor.suggested_file_name,
|
||||||
|
'sd_hash': managed_stream.descriptor.sd_hash,
|
||||||
|
'download_path': full_path,
|
||||||
|
'mime_type': managed_stream.mime_type,
|
||||||
|
'key': managed_stream.descriptor.key,
|
||||||
|
'total_bytes_lower_bound': managed_stream.descriptor.lower_bound_decrypted_length(),
|
||||||
|
'total_bytes': managed_stream.descriptor.upper_bound_decrypted_length(),
|
||||||
|
'written_bytes': written_bytes,
|
||||||
|
'blobs_completed': managed_stream.blobs_completed,
|
||||||
|
'blobs_in_stream': managed_stream.blobs_in_stream,
|
||||||
|
'blobs_remaining': managed_stream.blobs_remaining,
|
||||||
|
'status': managed_stream.status,
|
||||||
|
'claim_id': managed_stream.claim_id,
|
||||||
|
'txid': managed_stream.txid,
|
||||||
|
'nout': managed_stream.nout,
|
||||||
|
'outpoint': managed_stream.outpoint,
|
||||||
|
'claim': managed_stream.claim,
|
||||||
|
'metadata': managed_stream.metadata,
|
||||||
|
'protobuf': managed_stream.metadata_protobuf,
|
||||||
|
'channel_claim_id': managed_stream.channel_claim_id,
|
||||||
|
'channel_name': managed_stream.channel_name,
|
||||||
|
'claim_name': managed_stream.claim_name,
|
||||||
|
'content_fee': managed_stream.content_fee,
|
||||||
'height': tx_height,
|
'height': tx_height,
|
||||||
'confirmations': (best_height+1) - tx_height if tx_height > 0 else tx_height,
|
'confirmations': confirmations,
|
||||||
'timestamp': self.ledger.headers[tx_height]['timestamp'] if tx_height > 0 else None
|
'timestamp': timestamp
|
||||||
})
|
}
|
||||||
return file
|
|
||||||
|
|
||||||
def encode_claim(self, claim):
|
def encode_claim(self, claim):
|
||||||
encoded = getattr(claim, claim.claim_type).to_dict()
|
encoded = getattr(claim, claim.claim_type).to_dict()
|
||||||
|
|
|
@ -166,6 +166,10 @@ class ManagedStream:
|
||||||
def claim_name(self) -> typing.Optional[str]:
|
def claim_name(self) -> typing.Optional[str]:
|
||||||
return None if not self.stream_claim_info else self.stream_claim_info.claim_name
|
return None if not self.stream_claim_info else self.stream_claim_info.claim_name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def claim(self) -> typing.Optional['Claim']:
|
||||||
|
return None if not self.stream_claim_info else self.stream_claim_info.claim
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def metadata(self) -> typing.Optional[typing.Dict]:
|
def metadata(self) -> typing.Optional[typing.Dict]:
|
||||||
return None if not self.stream_claim_info else self.stream_claim_info.claim.stream.to_dict()
|
return None if not self.stream_claim_info else self.stream_claim_info.claim.stream.to_dict()
|
||||||
|
@ -201,55 +205,6 @@ class ManagedStream:
|
||||||
def mime_type(self):
|
def mime_type(self):
|
||||||
return guess_media_type(os.path.basename(self.descriptor.suggested_file_name))[0]
|
return guess_media_type(os.path.basename(self.descriptor.suggested_file_name))[0]
|
||||||
|
|
||||||
def as_dict(self) -> typing.Dict:
|
|
||||||
full_path = self.full_path
|
|
||||||
file_name = self.file_name
|
|
||||||
download_directory = self.download_directory
|
|
||||||
if self.full_path and self.output_file_exists:
|
|
||||||
if self.written_bytes:
|
|
||||||
written_bytes = self.written_bytes
|
|
||||||
else:
|
|
||||||
written_bytes = os.stat(self.full_path).st_size
|
|
||||||
else:
|
|
||||||
full_path = None
|
|
||||||
file_name = None
|
|
||||||
download_directory = None
|
|
||||||
written_bytes = None
|
|
||||||
return {
|
|
||||||
'streaming_url': f"http://{self.config.streaming_host}:{self.config.streaming_port}/stream/{self.sd_hash}",
|
|
||||||
'completed': (self.output_file_exists and (self.status in ('stopped', 'finished'))
|
|
||||||
or not self.saving.is_set()) or all(
|
|
||||||
self.blob_manager.is_blob_verified(b.blob_hash) for b in self.descriptor.blobs[:-1]),
|
|
||||||
'file_name': file_name,
|
|
||||||
'download_directory': download_directory,
|
|
||||||
'points_paid': 0.0,
|
|
||||||
'stopped': not self.running,
|
|
||||||
'stream_hash': self.stream_hash,
|
|
||||||
'stream_name': self.descriptor.stream_name,
|
|
||||||
'suggested_file_name': self.descriptor.suggested_file_name,
|
|
||||||
'sd_hash': self.descriptor.sd_hash,
|
|
||||||
'download_path': full_path,
|
|
||||||
'mime_type': self.mime_type,
|
|
||||||
'key': self.descriptor.key,
|
|
||||||
'total_bytes_lower_bound': self.descriptor.lower_bound_decrypted_length(),
|
|
||||||
'total_bytes': self.descriptor.upper_bound_decrypted_length(),
|
|
||||||
'written_bytes': written_bytes,
|
|
||||||
'blobs_completed': self.blobs_completed,
|
|
||||||
'blobs_in_stream': self.blobs_in_stream,
|
|
||||||
'blobs_remaining': self.blobs_remaining,
|
|
||||||
'status': self.status,
|
|
||||||
'claim_id': self.claim_id,
|
|
||||||
'txid': self.txid,
|
|
||||||
'nout': self.nout,
|
|
||||||
'outpoint': self.outpoint,
|
|
||||||
'metadata': self.metadata,
|
|
||||||
'protobuf': self.metadata_protobuf,
|
|
||||||
'channel_claim_id': self.channel_claim_id,
|
|
||||||
'channel_name': self.channel_name,
|
|
||||||
'claim_name': self.claim_name,
|
|
||||||
'content_fee': self.content_fee
|
|
||||||
}
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def create(cls, loop: asyncio.BaseEventLoop, config: 'Config', blob_manager: 'BlobManager',
|
async def create(cls, loop: asyncio.BaseEventLoop, config: 'Config', blob_manager: 'BlobManager',
|
||||||
file_path: str, key: typing.Optional[bytes] = None,
|
file_path: str, key: typing.Optional[bytes] = None,
|
||||||
|
|
Loading…
Add table
Reference in a new issue