add API for reposting

This commit is contained in:
Victor Shyba 2019-10-14 05:17:37 -03:00 committed by Lex Berezhny
parent 71f6542571
commit df6537fae8
3 changed files with 109 additions and 0 deletions

View file

@ -1,4 +1,5 @@
import os
import re
import asyncio
import logging
import json
@ -113,6 +114,8 @@ SHORT_ID_LEN = 20
MAX_UPDATE_FEE_ESTIMATE = 0.3
DEFAULT_PAGE_SIZE = 20
VALID_FULL_CLAIM_ID = re.compile('[0-9a-fA-F]{40}')
def encode_pagination_doc(items):
return {
@ -2812,6 +2815,84 @@ class Daemon(metaclass=JSONRPCServerType):
f"to update a specific stream claim."
)
@requires(WALLET_COMPONENT, STREAM_MANAGER_COMPONENT, BLOB_COMPONENT, DATABASE_COMPONENT)
async def jsonrpc_stream_repost(self, name, bid, claim_id, allow_duplicate_name=False, channel_id=None,
channel_name=None, channel_account_id=None, account_id=None, wallet_id=None,
claim_address=None, funding_account_ids=None, preview=False, blocking=False,
**kwargs):
"""
Creates a claim that references an existing stream by its claim id.
Usage:
stream_repost (<name> | --name=<name>) (<bid> | --bid=<bid>) (<claim_id> | --claim_id=<claim_id>)
[--allow_duplicate_name=<allow_duplicate_name>]
[--channel_id=<channel_id> | --channel_name=<channel_name>]
[--channel_account_id=<channel_account_id>...]
[--account_id=<account_id>] [--wallet_id=<wallet_id>]
[--claim_address=<claim_address>] [--funding_account_ids=<funding_account_ids>...]
[--preview] [--blocking]
Options:
--name=<name> : (str) name of the content (can only consist of a-z A-Z 0-9 and -(dash))
--bid=<bid> : (decimal) amount to back the claim
--allow_duplicate_name=<allow_duplicate_name> : (bool) create new claim even if one already exists with
given name. default: false.
--channel_id=<channel_id> : (str) claim id of the publisher channel
--channel_name=<channel_name> : (str) name of the publisher channel
--channel_account_id=<channel_account_id>: (str) one or more account ids for accounts to look in
for channel certificates, defaults to all accounts.
--account_id=<account_id> : (str) account to use for holding the transaction
--wallet_id=<wallet_id> : (str) restrict operation to specific wallet
--funding_account_ids=<funding_account_ids>: (list) ids of accounts to fund this transaction
--claim_address=<claim_address>: (str) address where the claim is sent to, if not specified
it will be determined automatically from the account
--preview : (bool) do not broadcast the transaction
--blocking : (bool) wait until transaction is in mempool
Returns: {Transaction}
"""
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
self.valid_stream_name_or_error(name)
account = wallet.get_account_or_default(account_id)
funding_accounts = wallet.get_accounts_or_all(funding_account_ids)
channel = await self.get_channel_or_none(wallet, channel_account_id, channel_id, channel_name, for_signing=True)
amount = self.get_dewies_or_error('bid', bid, positive_value=True)
claim_address = await self.get_receiving_address(claim_address, account)
claims = await account.get_claims(claim_name=name)
if len(claims) > 0:
if not allow_duplicate_name:
raise Exception(
f"You already have a stream claim published under the name '{name}'. "
f"Use --allow-duplicate-name flag to override."
)
if not VALID_FULL_CLAIM_ID.fullmatch(claim_id):
raise Exception('Invalid claim id. It is expected to be a 40 characters long hexadecimal string.')
claim = Claim()
claim.repost.reference.claim_id = claim_id
tx = await Transaction.claim_create(
name, claim, amount, claim_address, funding_accounts, funding_accounts[0], channel
)
new_txo = tx.outputs[0]
if not preview:
new_txo.script.generate()
if channel:
new_txo.sign(channel)
await tx.sign(funding_accounts)
if not preview:
await self.broadcast_or_release(tx, blocking)
#await self.storage.save_claims([self._old_get_temp_claim_info(
# tx, new_txo, claim_address, claim, name, dewies_to_lbc(amount)
#)])
# await self.analytics_manager.send_claim_action('publish') todo: what to send?
else:
await account.ledger.release_tx(tx)
return tx
@requires(WALLET_COMPONENT, STREAM_MANAGER_COMPONENT, BLOB_COMPONENT, DATABASE_COMPONENT)
async def jsonrpc_stream_create(
self, name, bid, file_path, allow_duplicate_name=False,

View file

@ -204,6 +204,16 @@ class CommandTestCase(IntegrationTestCase):
""" Synchronous version of `out` method. """
return json.loads(jsonrpc_dumps_pretty(value, ledger=self.ledger))['result']
async def stream_repost(self, claim_id, name='repost', bid='1.0', **kwargs):
tx = await self.out(
self.daemon.jsonrpc_stream_repost(claim_id=claim_id, name=name, bid=bid, **kwargs)
)
if kwargs.get('confirm', True):
await self.on_transaction_dict(tx)
await self.generate(1)
await self.on_transaction_dict(tx)
return tx
async def confirm_and_render(self, awaitable, confirm) -> Transaction:
tx = await awaitable
if confirm:

View file

@ -714,6 +714,24 @@ class StreamCommands(ClaimTestCase):
signed = await self.out(self.stream_create('bar', '1.0', channel_name='@spam', preview=True, confirm=False))
self.assertTrue(signed['outputs'][0]['is_channel_signature_valid'])
async def test_repost(self):
await self.out(self.channel_create('@goodies', '1.0'))
tx = await self.out(self.stream_create('newstuff', '1.1', channel_name='@goodies'))
claim_id = tx['outputs'][0]['claim_id']
await self.stream_repost(claim_id, 'newstuff-again', '1.1')
claim_list = await self.out(self.daemon.jsonrpc_claim_list())
reposts_on_claim_list = [claim for claim in claim_list if claim['value_type'] == 'repost']
self.assertEqual(len(reposts_on_claim_list), 1)
await self.out(self.channel_create('@reposting-goodies', '1.0'))
await self.stream_repost(claim_id, 'repost-on-channel', '1.1', channel_name='@reposting-goodies')
claim_list = await self.out(self.daemon.jsonrpc_claim_list())
reposts_on_claim_list = [claim for claim in claim_list if claim['value_type'] == 'repost']
self.assertEqual(len(reposts_on_claim_list), 2)
signed_reposts = [repost for repost in reposts_on_claim_list if repost.get('is_channel_signature_valid')]
self.assertEqual(len(signed_reposts), 1)
search_results = await self.claim_search(name='newstuff-again')
self.assertEqual(len(search_results), 1)
async def test_publish_updates_file_list(self):
tx = await self.out(self.stream_create(title='created'))
txo = tx['outputs'][0]