async def session_query(self, query_name, kwargs): offset, total = kwargs.get('offset', 0) if isinstance(kwargs, dict) else 0, 0 total_referenced = [] if query_name == 'resolve': total_referenced, response, censor = await self.resolve(*kwargs) else: cache_item = ResultCacheItem.from_cache(str(kwargs), self.search_cache) if cache_item.result is not None: return cache_item.result async with cache_item.lock: if cache_item.result: return cache_item.result censor = Censor(Censor.SEARCH) if kwargs.get('no_totals'): response, offset, total = await self.search(**kwargs, censor_type=Censor.NOT_CENSORED) else: response, offset, total = await self.search(**kwargs) censor.apply(response) total_referenced.extend(response) if censor.censored: response, _, _ = await self.search(**kwargs, censor_type=Censor.NOT_CENSORED) total_referenced.extend(response) result = Outputs.to_base64( response, await self._get_referenced_rows(total_referenced), offset, total, censor ) cache_item.result = result return result return Outputs.to_base64(response, await self._get_referenced_rows(total_referenced), offset, total, censor)
async def _inflate_outputs(self, query, accounts) -> Tuple[List[Output], dict, int, int]: encoded_outputs = await query outputs = Outputs.from_base64(encoded_outputs or b'') # TODO: why is the server returning None? txs = [] if len(outputs.txs) > 0: txs: List[Transaction] = await asyncio.gather(*( self.cache_transaction(*tx) for tx in outputs.txs )) if accounts: priced_claims = [] for tx in txs: for txo in tx.outputs: if txo.has_price: priced_claims.append(txo) if priced_claims: receipts = { txo.purchased_claim_id: txo for txo in await self.db.get_purchases( accounts=accounts, purchased_claim_id__in=[c.claim_id for c in priced_claims] ) } for txo in priced_claims: txo.purchase_receipt = receipts.get(txo.claim_id) txos, blocked = outputs.inflate(txs) return txos, blocked, outputs.offset, outputs.total
async def _inflate_outputs(self, query): outputs = Outputs.from_base64(await query) txs = [] if len(outputs.txs) > 0: txs = await asyncio.gather(*(self.cache_transaction(*tx) for tx in outputs.txs)) return outputs.inflate(txs), outputs.offset, outputs.total
async def _inflate_outputs(self, query, accounts): outputs = Outputs.from_base64(await query) txs = [] if len(outputs.txs) > 0: txs: List[Transaction] = await asyncio.gather( *(self.cache_transaction(*tx) for tx in outputs.txs)) if accounts: priced_claims = [] for tx in txs: for txo in tx.outputs: if txo.has_price: priced_claims.append(txo) if priced_claims: receipts = { txo.purchased_claim_id: txo for txo in await self.db.get_purchases( accounts=accounts, purchased_claim_id__in=[ c.claim_id for c in priced_claims ]) } for txo in priced_claims: txo.purchase_receipt = receipts.get(txo.claim_id) return outputs.inflate(txs), outputs.offset, outputs.total
def encode_result(result): return Outputs.to_bytes(*result)
async def cached_search(self, kwargs): total_referenced = [] cache_item = ResultCacheItem.from_cache(str(kwargs), self.search_cache) if cache_item.result is not None: return cache_item.result async with cache_item.lock: if cache_item.result: return cache_item.result censor = Censor(Censor.SEARCH) if kwargs.get('no_totals'): response, offset, total = await self.search( **kwargs, censor_type=Censor.NOT_CENSORED) else: response, offset, total = await self.search(**kwargs) censor.apply(response) total_referenced.extend(response) if censor.censored: response, _, _ = await self.search( **kwargs, censor_type=Censor.NOT_CENSORED) total_referenced.extend(response) response = [ ResolveResult(name=r['claim_name'], normalized_name=r['normalized_name'], claim_hash=r['claim_hash'], tx_num=r['tx_num'], position=r['tx_nout'], tx_hash=r['tx_hash'], height=r['height'], amount=r['amount'], short_url=r['short_url'], is_controlling=r['is_controlling'], canonical_url=r['canonical_url'], creation_height=r['creation_height'], activation_height=r['activation_height'], expiration_height=r['expiration_height'], effective_amount=r['effective_amount'], support_amount=r['support_amount'], last_takeover_height=r['last_take_over_height'], claims_in_channel=r['claims_in_channel'], channel_hash=r['channel_hash'], reposted_claim_hash=r['reposted_claim_hash'], reposted=r['reposted'], signature_valid=r['signature_valid']) for r in response ] extra = [ ResolveResult(name=r['claim_name'], normalized_name=r['normalized_name'], claim_hash=r['claim_hash'], tx_num=r['tx_num'], position=r['tx_nout'], tx_hash=r['tx_hash'], height=r['height'], amount=r['amount'], short_url=r['short_url'], is_controlling=r['is_controlling'], canonical_url=r['canonical_url'], creation_height=r['creation_height'], activation_height=r['activation_height'], expiration_height=r['expiration_height'], effective_amount=r['effective_amount'], support_amount=r['support_amount'], last_takeover_height=r['last_take_over_height'], claims_in_channel=r['claims_in_channel'], channel_hash=r['channel_hash'], reposted_claim_hash=r['reposted_claim_hash'], reposted=r['reposted'], signature_valid=r['signature_valid']) for r in await self._get_referenced_rows(total_referenced) ] result = Outputs.to_base64(response, extra, offset, total, censor) cache_item.result = result return result
async def _inflate_outputs( self, query, accounts, include_purchase_receipt=False, include_is_my_output=False, include_sent_supports=False, include_sent_tips=False, include_received_tips=False ) -> Tuple[List[Output], dict, int, int]: encoded_outputs = await query outputs = Outputs.from_base64( encoded_outputs or b'') # TODO: why is the server returning None? txs = [] if len(outputs.txs) > 0: txs: List[Transaction] = await asyncio.gather( *(self.cache_transaction(*tx) for tx in outputs.txs)) txos, blocked = outputs.inflate(txs) includes = (include_purchase_receipt, include_is_my_output, include_sent_supports, include_sent_tips) if accounts and any(includes): copies = [] receipts = {} if include_purchase_receipt: priced_claims = [] for txo in txos: if isinstance(txo, Output) and txo.has_price: priced_claims.append(txo) if priced_claims: receipts = { txo.purchased_claim_id: txo for txo in await self.db.get_purchases( accounts=accounts, purchased_claim_id__in=[ c.claim_id for c in priced_claims ]) } for txo in txos: if isinstance(txo, Output) and txo.can_decode_claim: # transactions and outputs are cached and shared between wallets # we don't want to leak informaion between wallet so we add the # wallet specific metadata on throw away copies of the txos txo_copy = copy.copy(txo) copies.append(txo_copy) if include_purchase_receipt: txo_copy.purchase_receipt = receipts.get(txo.claim_id) if include_is_my_output: mine = await self.db.get_txo_count( claim_id=txo.claim_id, txo_type__in=CLAIM_TYPES, is_my_output=True, is_spent=False, accounts=accounts) if mine: txo_copy.is_my_output = True else: txo_copy.is_my_output = False if include_sent_supports: supports = await self.db.get_txo_sum( claim_id=txo.claim_id, txo_type=TXO_TYPES['support'], is_my_input=True, is_my_output=True, is_spent=False, accounts=accounts) txo_copy.sent_supports = supports if include_sent_tips: tips = await self.db.get_txo_sum( claim_id=txo.claim_id, txo_type=TXO_TYPES['support'], is_my_input=True, is_my_output=False, accounts=accounts) txo_copy.sent_tips = tips if include_received_tips: tips = await self.db.get_txo_sum( claim_id=txo.claim_id, txo_type=TXO_TYPES['support'], is_my_input=False, is_my_output=True, accounts=accounts) txo_copy.received_tips = tips else: copies.append(txo) txos = copies return txos, blocked, outputs.offset, outputs.total
def resolve_to_bytes(urls) -> bytes: return Outputs.to_bytes(*resolve(urls))
def search_to_bytes(constraints) -> bytes: return Outputs.to_bytes(*search(constraints))