searching by fee_amount and fee_currency

This commit is contained in:
Lex Berezhny 2019-06-22 22:25:22 -04:00
parent 9e11fc1e99
commit 488c2e2f17
3 changed files with 43 additions and 9 deletions

View file

@ -1718,6 +1718,7 @@ class Daemon(metaclass=JSONRPCServerType):
[--trending_mixed=<trending_mixed>] [--trending_local=<trending_local>] [--trending_mixed=<trending_mixed>] [--trending_local=<trending_local>]
[--trending_global=<trending_global] [--trending_global=<trending_global]
[--claim_type=<claim_type>] [--stream_types=<stream_types>...] [--media_types=<media_types>...] [--claim_type=<claim_type>] [--stream_types=<stream_types>...] [--media_types=<media_types>...]
[--fee_currency=<fee_currency>] [--fee_amount=<fee_amount>]
[--any_tags=<any_tags>...] [--all_tags=<all_tags>...] [--not_tags=<not_tags>...] [--any_tags=<any_tags>...] [--all_tags=<all_tags>...] [--not_tags=<not_tags>...]
[--any_languages=<any_languages>...] [--all_languages=<all_languages>...] [--any_languages=<any_languages>...] [--all_languages=<all_languages>...]
[--not_languages=<not_languages>...] [--not_languages=<not_languages>...]
@ -1788,6 +1789,8 @@ class Daemon(metaclass=JSONRPCServerType):
--claim_type=<claim_type> : (str) filter by 'channel', 'stream' or 'unknown' --claim_type=<claim_type> : (str) filter by 'channel', 'stream' or 'unknown'
--stream_types=<stream_types> : (list) filter by 'video', 'image', 'document', etc --stream_types=<stream_types> : (list) filter by 'video', 'image', 'document', etc
--media_types=<media_types> : (list) filter by 'video/mp4', 'image/png', etc --media_types=<media_types> : (list) filter by 'video/mp4', 'image/png', etc
--fee_currency=<fee_currency> : (string) specify fee currency: LBC, BTC, USD
--fee_amount=<fee_amount> : (decimal) content download fee (supports equality constraints)
--any_tags=<any_tags> : (list) find claims containing any of the tags --any_tags=<any_tags> : (list) find claims containing any of the tags
--all_tags=<all_tags> : (list) find claims containing every tag --all_tags=<all_tags> : (list) find claims containing every tag
--not_tags=<not_tags> : (list) find claims not containing any of these tags --not_tags=<not_tags> : (list) find claims not containing any of these tags

View file

@ -3,7 +3,7 @@ import struct
from typing import Union, Tuple, Set, List from typing import Union, Tuple, Set, List
from binascii import unhexlify from binascii import unhexlify
from itertools import chain from itertools import chain
from decimal import Decimal
from torba.server.db import DB from torba.server.db import DB
from torba.server.util import class_logger from torba.server.util import class_logger
@ -106,6 +106,8 @@ class SQLDB:
-- streams -- streams
stream_type text, stream_type text,
media_type text, media_type text,
fee_amount integer default 0,
fee_currency text,
-- claims which are channels -- claims which are channels
public_key_bytes bytes, public_key_bytes bytes,
@ -144,6 +146,8 @@ class SQLDB:
create index if not exists claim_claim_type_idx on claim (claim_type); create index if not exists claim_claim_type_idx on claim (claim_type);
create index if not exists claim_stream_type_idx on claim (stream_type); create index if not exists claim_stream_type_idx on claim (stream_type);
create index if not exists claim_media_type_idx on claim (media_type); create index if not exists claim_media_type_idx on claim (media_type);
create index if not exists claim_fee_amount_idx on claim (fee_amount);
create index if not exists claim_fee_currency_idx on claim (fee_currency);
create index if not exists claim_signature_valid_idx on claim (signature_valid); create index if not exists claim_signature_valid_idx on claim (signature_valid);
@ -276,6 +280,8 @@ class SQLDB:
'stream_type': None, 'stream_type': None,
'media_type': None, 'media_type': None,
'release_time': None, 'release_time': None,
'fee_currency': None,
'fee_amount': None
} }
claims.append(claim_record) claims.append(claim_record)
@ -291,6 +297,9 @@ class SQLDB:
claim_record['stream_type'] = STREAM_TYPES[guess_stream_type(claim_record['media_type'])] claim_record['stream_type'] = STREAM_TYPES[guess_stream_type(claim_record['media_type'])]
if claim.stream.release_time: if claim.stream.release_time:
claim_record['release_time'] = claim.stream.release_time claim_record['release_time'] = claim.stream.release_time
if claim.stream.has_fee:
claim_record['fee_currency'] = claim.stream.fee.currency.lower()
claim_record['fee_amount'] = int(claim.stream.fee.amount*1000)
elif claim.is_channel: elif claim.is_channel:
claim_record['claim_type'] = CLAIM_TYPES['channel'] claim_record['claim_type'] = CLAIM_TYPES['channel']
@ -313,11 +322,13 @@ class SQLDB:
self.db.executemany(""" self.db.executemany("""
INSERT OR IGNORE INTO claim ( INSERT OR IGNORE INTO claim (
claim_hash, claim_id, claim_name, normalized, txo_hash, tx_position, amount, claim_hash, claim_id, claim_name, normalized, txo_hash, tx_position, amount,
claim_type, media_type, stream_type, timestamp, creation_timestamp, height, claim_type, media_type, stream_type, timestamp, creation_timestamp,
fee_currency, fee_amount, height,
creation_height, release_time, activation_height, expiration_height, short_url) creation_height, release_time, activation_height, expiration_height, short_url)
VALUES ( VALUES (
:claim_hash, :claim_id, :claim_name, :normalized, :txo_hash, :tx_position, :amount, :claim_hash, :claim_id, :claim_name, :normalized, :txo_hash, :tx_position, :amount,
:claim_type, :media_type, :stream_type, :timestamp, :timestamp, :height, :height, :claim_type, :media_type, :stream_type, :timestamp, :timestamp,
:fee_currency, :fee_amount, :height, :height,
CASE WHEN :release_time IS NOT NULL THEN :release_time ELSE :timestamp END, CASE WHEN :release_time IS NOT NULL THEN :release_time ELSE :timestamp END,
CASE WHEN :normalized NOT IN (SELECT normalized FROM claimtrie) THEN :height END, CASE WHEN :normalized NOT IN (SELECT normalized FROM claimtrie) THEN :height END,
CASE WHEN :height >= 137181 THEN :height+2102400 ELSE :height+262974 END, CASE WHEN :height >= 137181 THEN :height+2102400 ELSE :height+262974 END,
@ -334,7 +345,7 @@ class SQLDB:
UPDATE claim SET UPDATE claim SET
txo_hash=:txo_hash, tx_position=:tx_position, amount=:amount, height=:height, txo_hash=:txo_hash, tx_position=:tx_position, amount=:amount, height=:height,
claim_type=:claim_type, media_type=:media_type, stream_type=:stream_type, claim_type=:claim_type, media_type=:media_type, stream_type=:stream_type,
timestamp=:timestamp, timestamp=:timestamp, fee_amount=:fee_amount, fee_currency=:fee_currency,
release_time=CASE WHEN :release_time IS NOT NULL THEN :release_time ELSE release_time END release_time=CASE WHEN :release_time IS NOT NULL THEN :release_time ELSE release_time END
WHERE claim_hash=:claim_hash; WHERE claim_hash=:claim_hash;
""", claims) """, claims)
@ -753,10 +764,12 @@ class SQLDB:
postfix = '' postfix = ''
if isinstance(value, str): if isinstance(value, str):
if len(value) >= 2 and value[:2] in ops: if len(value) >= 2 and value[:2] in ops:
postfix, value = ops[value[:2]], int(value[2:]) postfix, value = ops[value[:2]], value[2:]
elif len(value) >= 1 and value[0] in ops: elif len(value) >= 1 and value[0] in ops:
postfix, value = ops[value[0]], int(value[1:]) postfix, value = ops[value[0]], value[1:]
constraints[f'claim.{constraint}{postfix}'] = value if constraint == 'fee_amount':
value = Decimal(value)*1000
constraints[f'claim.{constraint}{postfix}'] = int(value)
if constraints.pop('is_controlling', False): if constraints.pop('is_controlling', False):
if {'sequence', 'amount_order'}.isdisjoint(constraints): if {'sequence', 'amount_order'}.isdisjoint(constraints):
@ -821,6 +834,9 @@ class SQLDB:
if media_types: if media_types:
constraints['claim.media_type__in'] = media_types constraints['claim.media_type__in'] = media_types
if 'fee_currency' in constraints:
constraints['claim.fee_currency'] = constraints.pop('fee_currency').lower()
_apply_constraints_for_array_attributes(constraints, 'tag', clean_tags) _apply_constraints_for_array_attributes(constraints, 'tag', clean_tags)
_apply_constraints_for_array_attributes(constraints, 'language', lambda _: _) _apply_constraints_for_array_attributes(constraints, 'language', lambda _: _)
_apply_constraints_for_array_attributes(constraints, 'location', lambda _: _) _apply_constraints_for_array_attributes(constraints, 'location', lambda _: _)
@ -865,7 +881,7 @@ class SQLDB:
INTEGER_PARAMS = { INTEGER_PARAMS = {
'height', 'creation_height', 'activation_height', 'expiration_height', 'height', 'creation_height', 'activation_height', 'expiration_height',
'timestamp', 'creation_timestamp', 'release_time', 'timestamp', 'creation_timestamp', 'release_time', 'fee_amount',
'tx_position', 'channel_join', 'signature_valid', 'tx_position', 'channel_join', 'signature_valid',
'amount', 'effective_amount', 'support_amount', 'amount', 'effective_amount', 'support_amount',
'trending_group', 'trending_mixed', 'trending_group', 'trending_mixed',
@ -874,7 +890,7 @@ class SQLDB:
SEARCH_PARAMS = { SEARCH_PARAMS = {
'name', 'claim_id', 'txid', 'nout', 'channel', 'channel_ids', 'public_key_id', 'name', 'claim_id', 'txid', 'nout', 'channel', 'channel_ids', 'public_key_id',
'claim_type', 'stream_types', 'media_types', 'claim_type', 'stream_types', 'media_types', 'fee_currency',
'any_tags', 'all_tags', 'not_tags', 'any_tags', 'all_tags', 'not_tags',
'any_locations', 'all_locations', 'not_locations', 'any_locations', 'all_locations', 'not_locations',
'any_languages', 'all_languages', 'not_languages', 'any_languages', 'all_languages', 'not_languages',

View file

@ -232,6 +232,21 @@ class ClaimSearchCommand(ClaimTestCase):
await self.assertFindsClaims(claims, order_by=["^name"]) await self.assertFindsClaims(claims, order_by=["^name"])
async def test_search_by_fee(self):
claim1 = await self.stream_create('claim1', fee_amount='1.0', fee_currency='lbc')
claim2 = await self.stream_create('claim2', fee_amount='0.9', fee_currency='lbc')
claim3 = await self.stream_create('claim3', fee_amount='0.5', fee_currency='lbc')
claim4 = await self.stream_create('claim4', fee_amount='0.1', fee_currency='lbc')
claim5 = await self.stream_create('claim5', fee_amount='1.0', fee_currency='usd')
await self.assertFindsClaims([claim5, claim4, claim3, claim2, claim1], fee_amount='>0')
await self.assertFindsClaims([claim4, claim3, claim2, claim1], fee_currency='lbc')
await self.assertFindsClaims([claim3, claim2, claim1], fee_amount='>0.1', fee_currency='lbc')
await self.assertFindsClaims([claim4, claim3, claim2], fee_amount='<1.0', fee_currency='lbc')
await self.assertFindsClaims([claim3], fee_amount='0.5', fee_currency='lbc')
await self.assertFindsClaims([claim5], fee_currency='usd')
await self.assertFindsClaims([], fee_currency='foo')
async def test_claim_type_and_media_type_search(self): async def test_claim_type_and_media_type_search(self):
# create an invalid/unknown claim # create an invalid/unknown claim
address = await self.account.receiving.get_or_create_usable_address() address = await self.account.receiving.get_or_create_usable_address()