Merge pull request #586 from lbryio/lbryschema_2

Lbryschema integration
This commit is contained in:
Jack Robison 2017-04-04 22:00:07 -04:00 committed by GitHub
commit 6f909f9654
16 changed files with 132 additions and 102 deletions

View file

@ -14,7 +14,7 @@ at anytime.
* *
### Changed ### Changed
* * Use lbryschema library for metadata
* *
* *

View file

@ -15,7 +15,7 @@ Install [xcode command line tools](https://developer.xamarin.com/guides/testclou
Remaining dependencies can then be installed by running: Remaining dependencies can then be installed by running:
``` ```
brew install mpfr libmpc brew install mpfr libmpc protobuf
sudo easy_install pip sudo easy_install pip
sudo pip install virtualenv sudo pip install virtualenv
``` ```
@ -26,7 +26,7 @@ On Ubuntu (we recommend 16.04), install the following:
``` ```
sudo apt-get install libgmp3-dev build-essential python2.7 python2.7-dev \ sudo apt-get install libgmp3-dev build-essential python2.7 python2.7-dev \
python-pip git python-virtualenv libssl-dev libffi-dev python-pip git python-virtualenv libssl-dev libffi-dev python-protobuf
``` ```
If you're running another Linux flavor, install the equivalent of the above packages for your system. If you're running another Linux flavor, install the equivalent of the above packages for your system.

View file

@ -10,7 +10,7 @@ def get_sd_hash(stream_info):
if not stream_info: if not stream_info:
return None return None
try: try:
return stream_info['sources']['lbry_sd_hash'] return stream_info['stream']['source']['source']
except (KeyError, TypeError, ValueError): except (KeyError, TypeError, ValueError):
log.debug('Failed to get sd_hash from %s', stream_info, exc_info=True) log.debug('Failed to get sd_hash from %s', stream_info, exc_info=True)
return None return None

View file

@ -182,7 +182,7 @@ ADJUSTABLE_SETTINGS = {
# #
# TODO: writing json on the cmd line is a pain, come up with a nicer # TODO: writing json on the cmd line is a pain, come up with a nicer
# parser for this data structure. (maybe MAX_KEY_FEE': USD:25 # parser for this data structure. (maybe MAX_KEY_FEE': USD:25
'max_key_fee': (json.loads, {'USD': {'amount': 25.0, 'address': ''}}), 'max_key_fee': (json.loads, {'currency':'USD', 'amount': 25.0, 'address':''}),
'max_search_results': (int, 25), 'max_search_results': (int, 25),
'max_upload': (float, 0.0), 'max_upload': (float, 0.0),

View file

@ -1,6 +1,5 @@
import datetime import datetime
import logging import logging
import json
import os import os
from twisted.internet import threads, reactor, defer, task from twisted.internet import threads, reactor, defer, task
@ -8,7 +7,6 @@ from twisted.python.failure import Failure
from twisted.enterprise import adbapi from twisted.enterprise import adbapi
from collections import defaultdict, deque from collections import defaultdict, deque
from zope.interface import implements from zope.interface import implements
from jsonschema import ValidationError
from decimal import Decimal from decimal import Decimal
from lbryum import SimpleConfig, Network from lbryum import SimpleConfig, Network
@ -16,13 +14,17 @@ from lbryum.lbrycrd import COIN, RECOMMENDED_CLAIMTRIE_HASH_CONFIRMS
import lbryum.wallet import lbryum.wallet
from lbryum.commands import known_commands, Commands from lbryum.commands import known_commands, Commands
from lbryschema.claim import ClaimDict
from lbryschema.decode import smart_decode
from lbryschema.error import DecodeError
from lbrynet.core import utils
from lbrynet.core.sqlite_helpers import rerun_if_locked from lbrynet.core.sqlite_helpers import rerun_if_locked
from lbrynet.interfaces import IRequestCreator, IQueryHandlerFactory, IQueryHandler, IWallet from lbrynet.interfaces import IRequestCreator, IQueryHandlerFactory, IQueryHandler, IWallet
from lbrynet.core.client.ClientRequest import ClientRequest from lbrynet.core.client.ClientRequest import ClientRequest
from lbrynet.core.Error import (UnknownNameError, InvalidStreamInfoError, RequestCanceledError, from lbrynet.core.Error import (UnknownNameError, InvalidStreamInfoError, RequestCanceledError,
InsufficientFundsError) InsufficientFundsError)
from lbrynet.db_migrator.migrate1to2 import UNSET_NOUT from lbrynet.db_migrator.migrate1to2 import UNSET_NOUT
from lbrynet.metadata.Metadata import Metadata
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -479,7 +481,8 @@ class Wallet(object):
assert k in r, "getvalueforname response missing field %s" % k assert k in r, "getvalueforname response missing field %s" % k
def _log_success(claim_id): def _log_success(claim_id):
log.debug("lbry://%s complies with %s, claimid: %s", name, metadata.version, claim_id) log.debug("lbry://%s complies with %s, claimid: %s",
name, claim_dict.claim_dict['version'], claim_id)
return defer.succeed(None) return defer.succeed(None)
if 'error' in result: if 'error' in result:
@ -487,15 +490,17 @@ class Wallet(object):
return Failure(UnknownNameError(name)) return Failure(UnknownNameError(name))
_check_result_fields(result) _check_result_fields(result)
try: try:
metadata = Metadata(json.loads(result['value'])) claim_dict = smart_decode(result['value'].decode('hex'))
except (TypeError, ValueError, ValidationError): except (TypeError, ValueError, DecodeError):
return Failure(InvalidStreamInfoError(name, result['value'])) return Failure(InvalidStreamInfoError(name, result['value']))
sd_hash = metadata['sources']['lbry_sd_hash'] #TODO: what if keys don't exist here,
# probablly need get_sd_hash() function fro ClaimDict
sd_hash = utils.get_sd_hash(claim_dict.claim_dict)
claim_outpoint = ClaimOutpoint(result['txid'], result['nout']) claim_outpoint = ClaimOutpoint(result['txid'], result['nout'])
d = self._save_name_metadata(name, claim_outpoint, sd_hash) d = self._save_name_metadata(name, claim_outpoint, sd_hash)
d.addCallback(lambda _: self.get_claimid(name, result['txid'], result['nout'])) d.addCallback(lambda _: self.get_claimid(name, result['txid'], result['nout']))
d.addCallback(lambda cid: _log_success(cid)) d.addCallback(lambda cid: _log_success(cid))
d.addCallback(lambda _: metadata) d.addCallback(lambda _: claim_dict.claim_dict)
return d return d
def get_claim(self, name, claim_id): def get_claim(self, name, claim_id):
@ -529,7 +534,7 @@ class Wallet(object):
def _get_claim_for_return(claim): def _get_claim_for_return(claim):
if not claim: if not claim:
return False return False
claim['value'] = json.loads(claim['value']) claim['value'] = smart_decode(claim['value'].decode('hex')).claim_dict
return claim return claim
def _get_my_unspent_claim(claims): def _get_my_unspent_claim(claims):
@ -554,10 +559,11 @@ class Wallet(object):
d.addCallback(lambda r: self._get_claim_info(name, ClaimOutpoint(r['txid'], r['nout']))) d.addCallback(lambda r: self._get_claim_info(name, ClaimOutpoint(r['txid'], r['nout'])))
else: else:
d = self._get_claim_info(name, ClaimOutpoint(txid, nout)) d = self._get_claim_info(name, ClaimOutpoint(txid, nout))
# TODO: this catches every exception, fix this
d.addErrback(lambda _: False) d.addErrback(lambda _: False)
return d return d
def _format_claim_for_return(self, name, claim, metadata=None, meta_version=None): def _format_claim_for_return(self, name, claim, claim_dict, meta_version):
result = {} result = {}
result['claim_id'] = claim['claim_id'] result['claim_id'] = claim['claim_id']
result['amount'] = claim['effective_amount'] result['amount'] = claim['effective_amount']
@ -565,28 +571,27 @@ class Wallet(object):
result['name'] = name result['name'] = name
result['txid'] = claim['txid'] result['txid'] = claim['txid']
result['nout'] = claim['nout'] result['nout'] = claim['nout']
result['value'] = metadata if metadata else json.loads(claim['value']) result['value'] = claim_dict
result['supports'] = [ result['supports'] = [
{'txid': support['txid'], 'nout': support['nout']} for support in claim['supports']] {'txid': support['txid'], 'nout': support['nout']} for support in claim['supports']]
result['meta_version'] = ( result['meta_version'] = meta_version
meta_version if meta_version else result['value'].get('ver', '0.0.1'))
return result return result
def _get_claim_info(self, name, claim_outpoint): def _get_claim_info(self, name, claim_outpoint):
def _build_response(claim): def _build_response(claim):
try: try:
metadata = Metadata(json.loads(claim['value'])) claim_dict = smart_decode(claim['value'].decode('hex')).claim_dict
meta_ver = metadata.version meta_ver = claim_dict['stream']['metadata']['version']
sd_hash = metadata['sources']['lbry_sd_hash'] sd_hash = utils.get_sd_hash(claim_dict)
d = self._save_name_metadata(name, claim_outpoint, sd_hash) d = self._save_name_metadata(name, claim_outpoint, sd_hash)
except (TypeError, ValueError, ValidationError): except (TypeError, ValueError, KeyError, DecodeError):
metadata = claim['value'] claim_dict = claim['value']
meta_ver = "Non-compliant" meta_ver = "Non-compliant"
d = defer.succeed(None) d = defer.succeed(None)
d.addCallback(lambda _: self._format_claim_for_return(name, d.addCallback(lambda _: self._format_claim_for_return(name,
claim, claim,
metadata=metadata, claim_dict=claim_dict,
meta_version=meta_ver)) meta_version=meta_ver))
log.info( log.info(
"get claim info lbry://%s metadata: %s, claimid: %s", "get claim info lbry://%s metadata: %s, claimid: %s",
@ -622,8 +627,7 @@ class Wallet(object):
fee - transaction fee paid to make claim fee - transaction fee paid to make claim
claim_id - claim id of the claim claim_id - claim id of the claim
""" """
claim_dict = ClaimDict.load_dict(metadata)
_metadata = Metadata(metadata)
my_claim = yield self.get_my_claim(name) my_claim = yield self.get_my_claim(name)
if my_claim: if my_claim:
@ -632,13 +636,13 @@ class Wallet(object):
raise InsufficientFundsError() raise InsufficientFundsError()
old_claim_outpoint = ClaimOutpoint(my_claim['txid'], my_claim['nout']) old_claim_outpoint = ClaimOutpoint(my_claim['txid'], my_claim['nout'])
claim = yield self._send_name_claim_update(name, my_claim['claim_id'], claim = yield self._send_name_claim_update(name, my_claim['claim_id'],
old_claim_outpoint, _metadata, bid) old_claim_outpoint, claim_dict.serialized, bid)
claim['claim_id'] = my_claim['claim_id'] claim['claim_id'] = my_claim['claim_id']
else: else:
log.info("Making a new claim") log.info("Making a new claim")
if self.get_balance() < bid: if self.get_balance() < bid:
raise InsufficientFundsError() raise InsufficientFundsError()
claim = yield self._send_name_claim(name, _metadata, bid) claim = yield self._send_name_claim(name, claim_dict.serialized, bid)
if not claim['success']: if not claim['success']:
msg = 'Claim to name {} failed: {}'.format(name, claim['reason']) msg = 'Claim to name {} failed: {}'.format(name, claim['reason'])
@ -647,8 +651,8 @@ class Wallet(object):
claim = self._process_claim_out(claim) claim = self._process_claim_out(claim)
claim_outpoint = ClaimOutpoint(claim['txid'], claim['nout']) claim_outpoint = ClaimOutpoint(claim['txid'], claim['nout'])
log.info("Saving metadata for claim %s %d", claim['txid'], claim['nout']) log.info("Saving metadata for claim %s %d", claim['txid'], claim['nout'])
yield self._save_name_metadata(name, claim_outpoint,
yield self._save_name_metadata(name, claim_outpoint, _metadata['sources']['lbry_sd_hash']) utils.get_sd_hash(claim_dict.claim_dict))
defer.returnValue(claim) defer.returnValue(claim)
@defer.inlineCallbacks @defer.inlineCallbacks
@ -1015,26 +1019,26 @@ class LBRYumWallet(Wallet):
return self._run_cmd_as_defer_to_thread('getclaimsforname', name) return self._run_cmd_as_defer_to_thread('getclaimsforname', name)
@defer.inlineCallbacks @defer.inlineCallbacks
def _send_name_claim(self, name, val, amount): def _send_name_claim(self, name, value, amount):
broadcast = False broadcast = False
log.debug("Name claim %s %s %f", name, val, amount) log.debug("Name claim %s %f", name, amount)
tx = yield self._run_cmd_as_defer_succeed('claim', name, json.dumps(val), amount, broadcast) tx = yield self._run_cmd_as_defer_succeed('claim', name, value, amount, broadcast)
claim_out = yield self._broadcast_claim_transaction(tx) claim_out = yield self._broadcast_claim_transaction(tx)
defer.returnValue(claim_out) defer.returnValue(claim_out)
@defer.inlineCallbacks @defer.inlineCallbacks
def _send_name_claim_update(self, name, claim_id, claim_outpoint, value, amount): def _send_name_claim_update(self, name, claim_id, claim_outpoint, value, amount):
metadata = json.dumps(value) log.debug("Update %s %d %f %s %s", claim_outpoint['txid'], claim_outpoint['nout'],
log.debug("Update %s %d %f %s %s '%s'", claim_outpoint['txid'], claim_outpoint['nout'], amount, name, claim_id)
amount, name, claim_id, metadata)
broadcast = False broadcast = False
tx = yield self._run_cmd_as_defer_succeed( tx = yield self._run_cmd_as_defer_succeed(
'update', claim_outpoint['txid'], claim_outpoint['nout'], 'update', claim_outpoint['txid'], claim_outpoint['nout'],
name, claim_id, metadata, amount, broadcast name, claim_id, value, amount, broadcast
) )
claim_out = yield self._broadcast_claim_transaction(tx) claim_out = yield self._broadcast_claim_transaction(tx)
defer.returnValue(claim_out) defer.returnValue(claim_out)
@defer.inlineCallbacks @defer.inlineCallbacks
def _abandon_claim(self, claim_outpoint): def _abandon_claim(self, claim_outpoint):
log.debug("Abandon %s %s" % (claim_outpoint['txid'], claim_outpoint['nout'])) log.debug("Abandon %s %s" % (claim_outpoint['txid'], claim_outpoint['nout']))

View file

@ -112,7 +112,7 @@ def short_hash(hash_str):
def get_sd_hash(stream_info): def get_sd_hash(stream_info):
if not stream_info: if not stream_info:
return None return None
return stream_info['sources']['lbry_sd_hash'] return stream_info['stream']['source']['source']
def json_dumps_pretty(obj, **kwargs): def json_dumps_pretty(obj, **kwargs):

View file

@ -24,7 +24,8 @@ from lbrynet.conf import LBRYCRD_WALLET, LBRYUM_WALLET, PTC_WALLET
from lbrynet.reflector import reupload from lbrynet.reflector import reupload
from lbrynet.reflector import ServerFactory as reflector_server_factory from lbrynet.reflector import ServerFactory as reflector_server_factory
from lbrynet.metadata.Fee import FeeValidator from lbrynet.metadata.Fee import FeeValidator
from lbrynet.metadata.Metadata import verify_name_characters, Metadata from lbrynet.metadata.Metadata import verify_name_characters
from lbryschema.decode import smart_decode
from lbrynet.lbryfile.client.EncryptedFileDownloader import EncryptedFileSaverFactory from lbrynet.lbryfile.client.EncryptedFileDownloader import EncryptedFileSaverFactory
from lbrynet.lbryfile.client.EncryptedFileDownloader import EncryptedFileOpenerFactory from lbrynet.lbryfile.client.EncryptedFileDownloader import EncryptedFileOpenerFactory
from lbrynet.lbryfile.client.EncryptedFileOptions import add_lbry_file_to_sd_identifier from lbrynet.lbryfile.client.EncryptedFileOptions import add_lbry_file_to_sd_identifier
@ -710,15 +711,16 @@ class Daemon(AuthJSONRPCServer):
defer.returnValue((sd_hash, file_path)) defer.returnValue((sd_hash, file_path))
@defer.inlineCallbacks @defer.inlineCallbacks
def _publish_stream(self, name, bid, metadata, file_path=None): def _publish_stream(self, name, bid, claim_dict, file_path=None):
publisher = Publisher(self.session, self.lbry_file_manager, self.session.wallet) publisher = Publisher(self.session, self.lbry_file_manager, self.session.wallet)
verify_name_characters(name) verify_name_characters(name)
if bid <= 0.0: if bid <= 0.0:
raise Exception("Invalid bid") raise Exception("Invalid bid")
if not file_path: if not file_path:
claim_out = yield publisher.update_stream(name, bid, metadata) claim_out = yield publisher.publish_stream(name, bid, claim_dict)
else: else:
claim_out = yield publisher.publish_stream(name, file_path, bid, metadata) claim_out = yield publisher.create_and_publish_stream(name, bid, claim_dict, file_path)
if conf.settings['reflect_uploads']: if conf.settings['reflect_uploads']:
d = reupload.reflect_stream(publisher.lbry_file) d = reupload.reflect_stream(publisher.lbry_file)
d.addCallbacks(lambda _: log.info("Reflected new publication to lbry://%s", name), d.addCallbacks(lambda _: log.info("Reflected new publication to lbry://%s", name),
@ -827,7 +829,7 @@ class Daemon(AuthJSONRPCServer):
return d return d
def _get_est_cost_from_metadata(self, metadata, name): def _get_est_cost_from_metadata(self, metadata, name):
d = self.get_est_cost_from_sd_hash(metadata['sources']['lbry_sd_hash']) d = self.get_est_cost_from_sd_hash(utils.get_sd_hash(metadata))
def _handle_err(err): def _handle_err(err):
if isinstance(err, Failure): if isinstance(err, Failure):
@ -888,7 +890,7 @@ class Daemon(AuthJSONRPCServer):
lbry_file.txid, lbry_file.txid,
lbry_file.nout) lbry_file.nout)
try: try:
metadata = claim['value'] metadata = smart_decode(claim['value']).claim_dict
except: except:
metadata = None metadata = None
try: try:
@ -1425,9 +1427,10 @@ class Daemon(AuthJSONRPCServer):
""" """
def _get_claim(_claim_id, _claims): def _get_claim(_claim_id, _claims):
#TODO: do this in Wallet class
for claim in _claims['claims']: for claim in _claims['claims']:
if claim['claim_id'] == _claim_id: if claim['claim_id'] == _claim_id:
return Metadata(json.loads(claim['value'])) return smart_decode(claim['value']).claim_dict
log.info("Received request to get %s", name) log.info("Received request to get %s", name)
@ -1476,9 +1479,11 @@ class Daemon(AuthJSONRPCServer):
result = yield self._get_lbry_file_dict(self.streams[name].downloader, result = yield self._get_lbry_file_dict(self.streams[name].downloader,
full_status=True) full_status=True)
except Exception as e: except Exception as e:
# TODO: should reraise here, instead of returning e.message
log.warning('Failed to get %s', name) log.warning('Failed to get %s', name)
self.analytics_manager.send_download_errored(download_id, name, stream_info) self.analytics_manager.send_download_errored(download_id, name, stream_info)
result = e.message result = e.message
response = yield self._render_response(result) response = yield self._render_response(result)
defer.returnValue(response) defer.returnValue(response)
@ -1672,17 +1677,25 @@ class Daemon(AuthJSONRPCServer):
metadata['preview'] = preview metadata['preview'] = preview
if nsfw is not None: if nsfw is not None:
metadata['nsfw'] = bool(nsfw) metadata['nsfw'] = bool(nsfw)
if sources is not None:
metadata['sources'] = sources
# add address to fee if unspecified metadata['version'] = '_0_1_0'
# original format {'currency':{'address','amount'}}
# add address to fee if unspecified {'version': ,'currency', 'address' , 'amount'}
if 'fee' in metadata: if 'fee' in metadata:
new_fee_dict = {}
assert len(metadata['fee']) == 1, "Too many fees" assert len(metadata['fee']) == 1, "Too many fees"
for currency in metadata['fee']: currency, fee_dict = metadata['fee'].items()[0]
if 'address' not in metadata['fee'][currency]: if 'address' not in fee_dict:
new_address = yield self.session.wallet.get_new_address() address = yield self.session.wallet.get_new_address()
metadata['fee'][currency]['address'] = new_address else:
metadata['fee'] = FeeValidator(metadata['fee']) address = fee_dict['address']
new_fee_dict = {
'version':'_0_0_1',
'currency': currency,
'address':address,
'amount':fee_dict['amount']}
metadata['fee'] = new_fee_dict
log.info("Publish: %s", { log.info("Publish: %s", {
'name': name, 'name': name,
@ -1692,7 +1705,15 @@ class Daemon(AuthJSONRPCServer):
'fee': fee, 'fee': fee,
}) })
result = yield self._publish_stream(name, bid, metadata, file_path) claim_dict = {
'version':'_0_0_1',
'claimType':'streamType',
'stream':{'metadata':metadata, 'version':'_0_0_1'}}
if sources is not None:
claim_dict['stream']['source'] = sources
result = yield self._publish_stream(name, bid, claim_dict, file_path)
response = yield self._render_response(result) response = yield self._render_response(result)
defer.returnValue(response) defer.returnValue(response)

View file

@ -3,6 +3,7 @@ import os
from twisted.internet import defer from twisted.internet import defer
from twisted.internet.task import LoopingCall from twisted.internet.task import LoopingCall
from lbrynet.core import utils
from lbrynet.core.Error import InsufficientFundsError, KeyFeeAboveMaxAllowed from lbrynet.core.Error import InsufficientFundsError, KeyFeeAboveMaxAllowed
from lbrynet.core.StreamDescriptor import download_sd_blob from lbrynet.core.StreamDescriptor import download_sd_blob
from lbrynet.metadata.Fee import FeeValidator from lbrynet.metadata.Fee import FeeValidator
@ -158,9 +159,9 @@ class GetStream(object):
@defer.inlineCallbacks @defer.inlineCallbacks
def download(self, stream_info, name): def download(self, stream_info, name):
self.set_status(INITIALIZING_CODE, name) self.set_status(INITIALIZING_CODE, name)
self.sd_hash = stream_info['sources']['lbry_sd_hash'] self.sd_hash = utils.get_sd_hash(stream_info)
if 'fee' in stream_info: if 'fee' in stream_info['stream']['metadata']:
fee = self.check_fee(stream_info['fee']) fee = self.check_fee(stream_info['stream']['metadata']['fee'])
else: else:
fee = None fee = None

View file

@ -193,11 +193,10 @@ class ExchangeRateManager(object):
fee_in = fee fee_in = fee
return FeeValidator({ return FeeValidator({
fee_in.currency_symbol: { 'currency':fee_in.currency_symbol,
'amount': self.convert_currency(fee_in.currency_symbol, "LBC", fee_in.amount), 'amount': self.convert_currency(fee_in.currency_symbol, "LBC", fee_in.amount),
'address': fee_in.address 'address': fee_in.address
} })
})
class DummyBTCLBCFeed(MarketFeed): class DummyBTCLBCFeed(MarketFeed):
@ -252,8 +251,7 @@ class DummyExchangeRateManager(object):
fee_in = fee fee_in = fee
return FeeValidator({ return FeeValidator({
fee_in.currency_symbol: { 'currency':fee_in.currency_symbol,
'amount': self.convert_currency(fee_in.currency_symbol, "LBC", fee_in.amount), 'amount': self.convert_currency(fee_in.currency_symbol, "LBC", fee_in.amount),
'address': fee_in.address 'address': fee_in.address
} })
})

View file

@ -3,10 +3,10 @@ import mimetypes
import os import os
from twisted.internet import defer from twisted.internet import defer
from lbrynet.core import file_utils from lbrynet.core import file_utils
from lbrynet.lbryfilemanager.EncryptedFileCreator import create_lbry_file from lbrynet.lbryfilemanager.EncryptedFileCreator import create_lbry_file
from lbrynet.lbryfile.StreamDescriptor import publish_sd_blob from lbrynet.lbryfile.StreamDescriptor import publish_sd_blob
from lbrynet.metadata.Metadata import Metadata
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -19,8 +19,11 @@ class Publisher(object):
self.wallet = wallet self.wallet = wallet
self.lbry_file = None self.lbry_file = None
"""
Create lbry file and make claim
"""
@defer.inlineCallbacks @defer.inlineCallbacks
def publish_stream(self, name, file_path, bid, metadata): def create_and_publish_stream(self, name, bid, claim_dict, file_path):
log.info('Starting publish for %s', name) log.info('Starting publish for %s', name)
file_name = os.path.basename(file_path) file_name = os.path.basename(file_path)
with file_utils.get_read_handle(file_path) as read_handle: with file_utils.get_read_handle(file_path) as read_handle:
@ -30,30 +33,30 @@ class Publisher(object):
self.lbry_file = yield self.lbry_file_manager.add_lbry_file(stream_hash, prm) self.lbry_file = yield self.lbry_file_manager.add_lbry_file(stream_hash, prm)
sd_hash = yield publish_sd_blob(self.lbry_file_manager.stream_info_manager, sd_hash = yield publish_sd_blob(self.lbry_file_manager.stream_info_manager,
self.session.blob_manager, self.lbry_file.stream_hash) self.session.blob_manager, self.lbry_file.stream_hash)
if 'sources' not in metadata: if 'source' not in claim_dict['stream']:
metadata['sources'] = {} claim_dict['stream']['source'] = {}
metadata['sources']['lbry_sd_hash'] = sd_hash claim_dict['stream']['source']['source'] = sd_hash
metadata['content_type'] = get_content_type(file_path) claim_dict['stream']['source']['sourceType'] = 'lbry_sd_hash'
metadata['ver'] = Metadata.current_version claim_dict['stream']['source']['contentType'] = get_content_type(file_path)
claim_out = yield self.make_claim(name, bid, metadata) claim_dict['stream']['source']['version'] = "_0_0_1" # need current version here
claim_out = yield self.make_claim(name, bid, claim_dict)
self.lbry_file.completed = True self.lbry_file.completed = True
yield self.lbry_file.load_file_attributes() yield self.lbry_file.load_file_attributes()
yield self.lbry_file.save_status() yield self.lbry_file.save_status()
defer.returnValue(claim_out) defer.returnValue(claim_out)
"""
Make a claim without creating a lbry file
"""
@defer.inlineCallbacks @defer.inlineCallbacks
def update_stream(self, name, bid, metadata): def publish_stream(self, name, bid, claim_dict):
my_claim = yield self.wallet.get_my_claim(name) claim_out = yield self.make_claim(name, bid, claim_dict)
updated_metadata = my_claim['value']
for meta_key in metadata:
updated_metadata[meta_key] = metadata[meta_key]
claim_out = yield self.make_claim(name, bid, updated_metadata)
defer.returnValue(claim_out) defer.returnValue(claim_out)
@defer.inlineCallbacks @defer.inlineCallbacks
def make_claim(self, name, bid, metadata): def make_claim(self, name, bid, claim_dict):
validated_metadata = Metadata(metadata) claim_out = yield self.wallet.claim_name(name, bid, claim_dict)
claim_out = yield self.wallet.claim_name(name, bid, validated_metadata)
defer.returnValue(claim_out) defer.returnValue(claim_out)

View file

@ -14,12 +14,12 @@ class FeeValidator(StructuredDict):
StructuredDict.__init__(self, fee, fee.get('ver', '0.0.1')) StructuredDict.__init__(self, fee, fee.get('ver', '0.0.1'))
self.currency_symbol = self.keys()[0] self.currency_symbol = self['currency']
self.amount = self._get_amount() self.amount = self._get_amount()
self.address = self[self.currency_symbol]['address'] self.address = self['address']
def _get_amount(self): def _get_amount(self):
amt = self[self.currency_symbol]['amount'] amt = self['amount']
try: try:
return float(amt) return float(amt)
except TypeError: except TypeError:

View file

@ -11,6 +11,7 @@ jsonrpc==1.2
jsonrpclib==0.1.7 jsonrpclib==0.1.7
jsonschema==2.5.1 jsonschema==2.5.1
git+https://github.com/lbryio/lbryum.git git+https://github.com/lbryio/lbryum.git
git+https://github.com/lbryio/lbryschema.git
miniupnpc==1.9 miniupnpc==1.9
pbkdf2==1.3 pbkdf2==1.3
protobuf==3.0.0 protobuf==3.0.0

View file

@ -20,6 +20,7 @@ requires = [
'jsonrpc', 'jsonrpc',
'jsonschema', 'jsonschema',
'lbryum>=2.7.6', 'lbryum>=2.7.6',
'lbryschema',
'miniupnpc', 'miniupnpc',
'pycrypto', 'pycrypto',
'pyyaml', 'pyyaml',

View file

@ -8,19 +8,21 @@ from lbrynet.core.Wallet import Wallet, ReservedPoints
test_metadata = { test_metadata = {
'license': 'NASA', 'license': 'NASA',
'fee': {'USD': {'amount': 0.01, 'address': 'baBYSK7CqGSn5KrEmNmmQwAhBSFgo6v47z'}}, 'version': '_0_1_0',
'ver': '0.0.3',
'description': 'test', 'description': 'test',
'language': 'en', 'language': 'en',
'author': 'test', 'author': 'test',
'title': 'test', 'title': 'test',
'sources': {
'lbry_sd_hash': '8655f713819344980a9a0d67b198344e2c462c90f813e86f0c63789ab0868031f25c54d0bb31af6658e997e2041806eb'},
'nsfw': False, 'nsfw': False,
'content_type': 'video/mp4',
'thumbnail': 'test' 'thumbnail': 'test'
} }
test_claim_dict = {
'version':'_0_0_1',
'claimType':'streamType',
'stream':{'metadata':test_metadata, 'version':'_0_0_1','source':{'source':'8655f713819344980a9a0d67b198344e2c462c90f813e86f0c63789ab0868031f25c54d0bb31af6658e997e2041806eb','sourceType':'lbry_sd_hash','contentType':'video/mp4','version':'_0_0_1'},
}}
class MocLbryumWallet(Wallet): class MocLbryumWallet(Wallet):
def __init__(self): def __init__(self):
@ -42,7 +44,7 @@ class WalletTest(unittest.TestCase):
return claim_out return claim_out
MocLbryumWallet._send_name_claim = not_enough_funds_send_name_claim MocLbryumWallet._send_name_claim = not_enough_funds_send_name_claim
wallet = MocLbryumWallet() wallet = MocLbryumWallet()
d = wallet.claim_name('test', 1, test_metadata) d = wallet.claim_name('test', 1, test_claim_dict)
self.assertFailure(d,Exception) self.assertFailure(d,Exception)
return d return d
@ -67,7 +69,7 @@ class WalletTest(unittest.TestCase):
MocLbryumWallet._send_name_claim = success_send_name_claim MocLbryumWallet._send_name_claim = success_send_name_claim
wallet = MocLbryumWallet() wallet = MocLbryumWallet()
d = wallet.claim_name('test', 1, test_metadata) d = wallet.claim_name('test', 1, test_claim_dict)
d.addCallback(lambda claim_out: check_out(claim_out)) d.addCallback(lambda claim_out: check_out(claim_out))
return d return d
@ -169,7 +171,7 @@ class WalletTest(unittest.TestCase):
d = wallet.update_balance() d = wallet.update_balance()
d.addCallback(lambda _: self.assertEqual(5, wallet.get_balance())) d.addCallback(lambda _: self.assertEqual(5, wallet.get_balance()))
d.addCallback(lambda _: wallet.reserve_points('testid',2)) d.addCallback(lambda _: wallet.reserve_points('testid',2))
d.addCallback(lambda _: wallet.claim_name('test', 4, test_metadata)) d.addCallback(lambda _: wallet.claim_name('test', 4, test_claim_dict))
self.assertFailure(d,InsufficientFundsError) self.assertFailure(d,InsufficientFundsError)
return d return d

View file

@ -80,7 +80,7 @@ def get_test_daemon(data_rate=None, generous=True, with_fee=False):
} }
if with_fee: if with_fee:
metadata.update( metadata.update(
{"fee": {"USD": {"address": "bQ6BGboPV2SpTMEP7wLNiAcnsZiH8ye6eA", "amount": 0.75}}}) {"fee": {"currency":"USD", "address":"bQ6BGboPV2SpTMEP7wLNiAcnsZiH8ye6eA", "amount": 0.75}})
daemon._resolve_name = lambda _: defer.succeed(metadata) daemon._resolve_name = lambda _: defer.succeed(metadata)
return daemon return daemon

View file

@ -11,14 +11,13 @@ from tests import util
class FeeFormatTest(unittest.TestCase): class FeeFormatTest(unittest.TestCase):
def test_fee_created_with_correct_inputs(self): def test_fee_created_with_correct_inputs(self):
fee_dict = { fee_dict = {
'USD': { 'currency':'USD',
'amount': 10.0, 'amount': 10.0,
'address': "bRcHraa8bYJZL7vkh5sNmGwPDERFUjGPP9" 'address': "bRcHraa8bYJZL7vkh5sNmGwPDERFUjGPP9"
}
} }
fee = Fee.FeeValidator(fee_dict) fee = Fee.FeeValidator(fee_dict)
self.assertEqual(10.0, fee['USD']['amount']) self.assertEqual(10.0, fee['amount'])
self.assertEqual('USD', fee['currency'])
class FeeTest(unittest.TestCase): class FeeTest(unittest.TestCase):
def setUp(self): def setUp(self):
@ -26,11 +25,11 @@ class FeeTest(unittest.TestCase):
def test_fee_converts_to_lbc(self): def test_fee_converts_to_lbc(self):
fee_dict = { fee_dict = {
'USD': { 'currency':'USD',
'amount': 10.0, 'amount': 10.0,
'address': "bRcHraa8bYJZL7vkh5sNmGwPDERFUjGPP9" 'address': "bRcHraa8bYJZL7vkh5sNmGwPDERFUjGPP9"
} }
}
rates = { rates = {
'BTCLBC': {'spot': 3.0, 'ts': util.DEFAULT_ISO_TIME + 1}, 'BTCLBC': {'spot': 3.0, 'ts': util.DEFAULT_ISO_TIME + 1},
'USDBTC': {'spot': 2.0, 'ts': util.DEFAULT_ISO_TIME + 2} 'USDBTC': {'spot': 2.0, 'ts': util.DEFAULT_ISO_TIME + 2}