publish updates
-adds a base set of metadata fields required for results to be rendered in conf.py, including language and content-type -dont support old style claims on the new blockchain
This commit is contained in:
parent
f89486f5fe
commit
7cc3e9d5ef
6 changed files with 98 additions and 150 deletions
|
@ -4,5 +4,5 @@ log = logging.getLogger(__name__)
|
|||
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
||||
log.setLevel(logging.ERROR)
|
||||
|
||||
version = (0, 2, 5)
|
||||
version = (0, 2, 6)
|
||||
__version__ = ".".join([str(x) for x in version])
|
||||
|
|
|
@ -17,9 +17,9 @@ MIN_VALUABLE_BLOB_HASH_PAYMENT_RATE = .05 # points/1000 infos
|
|||
MAX_CONNECTIONS_PER_STREAM = 5
|
||||
|
||||
KNOWN_DHT_NODES = [('104.236.42.182', 4000),
|
||||
('lbryum1.lbry.io', 4444),
|
||||
('lbryum2.lbry.io', 4444),
|
||||
('lbryum3.lbry.io', 4444)]
|
||||
('lbrynet1.lbry.io', 4444),
|
||||
('lbrynet2.lbry.io', 4444),
|
||||
('lbrynet3.lbry.io', 4444)]
|
||||
|
||||
POINTTRADER_SERVER = 'http://ec2-54-187-192-68.us-west-2.compute.amazonaws.com:2424'
|
||||
#POINTTRADER_SERVER = 'http://127.0.0.1:2424'
|
||||
|
@ -35,7 +35,7 @@ API_PORT = 5279
|
|||
ICON_PATH = "app.icns"
|
||||
APP_NAME = "LBRY"
|
||||
API_CONNECTION_STRING = "http://%s:%i/%s" % (API_INTERFACE, API_PORT, API_ADDRESS)
|
||||
UI_ADDRESS = "http://" + API_INTERFACE + ":" + str(API_PORT)
|
||||
UI_ADDRESS = "http://%s:%i" % (API_INTERFACE, API_PORT)
|
||||
PROTOCOL_PREFIX = "lbry"
|
||||
|
||||
DEFAULT_WALLET = "lbryum"
|
||||
|
@ -46,3 +46,7 @@ DEFAULT_MAX_KEY_FEE = 100.0
|
|||
DEFAULT_SEARCH_TIMEOUT = 3.0
|
||||
DEFAULT_CACHE_TIME = 3600
|
||||
DEFAULT_UI_BRANCH = "master"
|
||||
|
||||
SOURCE_TYPES = ['lbry_sd_hash', 'url', 'btih']
|
||||
BASE_METADATA_FIELDS = ['title', 'description', 'author', 'language', 'license', 'content-type']
|
||||
OPTIONAL_METADATA_FIELDS = ['thumbnail', 'preview', 'fee', 'contact', 'pubkey']
|
|
@ -4,6 +4,7 @@ from lbrynet.core.client.ClientRequest import ClientRequest
|
|||
from lbrynet.core.Error import UnknownNameError, InvalidStreamInfoError, RequestCanceledError
|
||||
from lbrynet.core.Error import InsufficientFundsError
|
||||
from lbrynet.core.sqlite_helpers import rerun_if_locked
|
||||
from lbrynet.conf import BASE_METADATA_FIELDS, SOURCE_TYPES, OPTIONAL_METADATA_FIELDS
|
||||
|
||||
from lbryum import SimpleConfig, Network
|
||||
from lbryum.bitcoin import COIN, TYPE_ADDRESS
|
||||
|
@ -318,68 +319,51 @@ class LBRYWallet(object):
|
|||
r_dict = {}
|
||||
if 'value' in result:
|
||||
value = result['value']
|
||||
|
||||
try:
|
||||
value_dict = json.loads(value)
|
||||
except (ValueError, TypeError):
|
||||
return Failure(InvalidStreamInfoError(name))
|
||||
known_fields = ['stream_hash', 'name', 'description', 'key_fee', 'key_fee_address', 'thumbnail',
|
||||
'content_license', 'sources', 'fee', 'author']
|
||||
known_sources = ['lbry_sd_hash', 'btih', 'url']
|
||||
known_fee_types = {'LBC': ['amount', 'address']}
|
||||
for field in known_fields:
|
||||
if field in value_dict:
|
||||
if field == 'sources':
|
||||
for source in known_sources:
|
||||
if source in value_dict[field]:
|
||||
if source == 'lbry_sd_hash':
|
||||
r_dict['stream_hash'] = value_dict[field][source]
|
||||
else:
|
||||
r_dict[source] = value_dict[field][source]
|
||||
elif field == 'fee':
|
||||
fee = value_dict['fee']
|
||||
if 'type' in fee:
|
||||
if fee['type'] in known_fee_types:
|
||||
fee_fields = known_fee_types[fee['type']]
|
||||
if all([f in fee for f in fee_fields]):
|
||||
r_dict['key_fee'] = fee['amount']
|
||||
r_dict['key_fee_address'] = fee['address']
|
||||
else:
|
||||
for f in ['key_fee', 'key_fee_address']:
|
||||
if f in r_dict:
|
||||
del r_dict[f]
|
||||
else:
|
||||
r_dict['sources'] = value_dict['sources']
|
||||
for field in BASE_METADATA_FIELDS:
|
||||
r_dict[field] = value_dict[field]
|
||||
if 'stream_hash' in r_dict and 'txid' in result:
|
||||
d = self._save_name_metadata(name, r_dict['stream_hash'], str(result['txid']))
|
||||
else:
|
||||
d = defer.succeed(True)
|
||||
for field in value_dict:
|
||||
if field in OPTIONAL_METADATA_FIELDS:
|
||||
r_dict[field] = value_dict[field]
|
||||
|
||||
if 'txid' in result:
|
||||
d = self._save_name_metadata(name, r_dict['sources']['lbry_sd_hash'], str(result['txid']))
|
||||
d.addCallback(lambda _: r_dict)
|
||||
return d
|
||||
elif 'error' in result:
|
||||
log.warning("Got an error looking up a name: %s", result['error'])
|
||||
return Failure(UnknownNameError(name))
|
||||
else:
|
||||
log.warning("Got an error looking up a name: %s", json.dumps(result))
|
||||
return Failure(UnknownNameError(name))
|
||||
|
||||
def claim_name(self, name, sd_hash, amount, description=None, key_fee=None,
|
||||
key_fee_address=None, thumbnail=None, content_license=None, author=None, sources=None):
|
||||
value = {"sources": {'lbry_sd_hash': sd_hash}}
|
||||
if description is not None:
|
||||
value['description'] = description
|
||||
if key_fee is not None and key_fee_address is not None:
|
||||
value['fee'] = {'type': 'LBC', 'amount': key_fee, 'address': key_fee_address}
|
||||
if thumbnail is not None:
|
||||
value['thumbnail'] = thumbnail
|
||||
if content_license is not None:
|
||||
value['content_license'] = content_license
|
||||
if author is not None:
|
||||
value['author'] = author
|
||||
if isinstance(sources, dict):
|
||||
sources['lbry_sd_hash'] = sd_hash
|
||||
value['sources'] = sources
|
||||
def claim_name(self, name, bid, sources, metadata, fee=None):
|
||||
value = {'sources': {}}
|
||||
for k in SOURCE_TYPES:
|
||||
if k in sources:
|
||||
value['sources'][k] = sources[k]
|
||||
if value['sources'] == {}:
|
||||
return defer.fail("No source given")
|
||||
for k in BASE_METADATA_FIELDS:
|
||||
if k not in metadata:
|
||||
return defer.fail("Missing required field '%s'" % k)
|
||||
value[k] = metadata[k]
|
||||
for k in metadata:
|
||||
if k not in BASE_METADATA_FIELDS:
|
||||
value[k] = metadata[k]
|
||||
if fee is not None:
|
||||
if "LBC" in fee:
|
||||
value['fee'] = {'LBC': {'amount': fee['LBC']['amount'], 'address': fee['LBC']['address']}}
|
||||
|
||||
d = self._send_name_claim(name, json.dumps(value), amount)
|
||||
d = self._send_name_claim(name, json.dumps(value), bid)
|
||||
|
||||
def _save_metadata(txid):
|
||||
d = self._save_name_metadata(name, sd_hash, txid)
|
||||
d = self._save_name_metadata(name, value['sources']['lbry_sd_hash'], txid)
|
||||
d.addCallback(lambda _: txid)
|
||||
return d
|
||||
|
||||
|
@ -409,7 +393,7 @@ class LBRYWallet(object):
|
|||
def abandon(results):
|
||||
if results[0][0] and results[1][0]:
|
||||
address = results[0][1]
|
||||
amount = results[1][1]
|
||||
amount = float(results[1][1])
|
||||
return self._send_abandon(txid, address, amount)
|
||||
elif results[0][0] is False:
|
||||
return defer.fail(Failure(ValueError("Couldn't get a new address")))
|
||||
|
@ -826,7 +810,7 @@ class LBRYcrdWallet(LBRYWallet):
|
|||
@_catch_connection_error
|
||||
def _send_abandon_rpc(self, txid, address, amount):
|
||||
rpc_conn = self._get_rpc_conn()
|
||||
return rpc_conn.abandonname(txid, address, amount)
|
||||
return rpc_conn.abandonclaim(txid, address, amount)
|
||||
|
||||
@_catch_connection_error
|
||||
def _get_blockchain_info_rpc(self):
|
||||
|
|
|
@ -1151,12 +1151,11 @@ class LBRYDaemon(jsonrpc.JSONRPC):
|
|||
|
||||
def _add_key_fee(data_cost):
|
||||
d = self._resolve_name(name)
|
||||
d.addCallback(lambda info: data_cost + info['key_fee'] if 'key_fee' in info.keys() else data_cost)
|
||||
d.addCallback(lambda info: data_cost if 'fee' not in info else data_cost + info['fee']['LBC']['amount'])
|
||||
return d
|
||||
|
||||
d = self._resolve_name(name)
|
||||
d.addCallback(lambda info: info['stream_hash'] if isinstance(info['stream_hash'], str)
|
||||
else info['stream_hash']['sd_hash'])
|
||||
d.addCallback(lambda info: info['sources']['lbry_sd_hash'])
|
||||
d.addCallback(lambda sd_hash: download_sd_blob(self.session, sd_hash,
|
||||
self.blob_request_payment_rate_manager))
|
||||
d.addCallback(self.sd_identifier.get_metadata_for_sd_blob)
|
||||
|
@ -1170,10 +1169,7 @@ class LBRYDaemon(jsonrpc.JSONRPC):
|
|||
|
||||
def _get_lbry_file_by_uri(self, name):
|
||||
def _get_file(stream_info):
|
||||
if isinstance(stream_info['stream_hash'], str) or isinstance(stream_info['stream_hash'], unicode):
|
||||
sd = stream_info['stream_hash']
|
||||
elif isinstance(stream_info['stream_hash'], dict):
|
||||
sd = stream_info['stream_hash']['sd_hash']
|
||||
sd = stream_info['sources']['lbry_sd_hash']
|
||||
|
||||
for l in self.lbry_file_manager.lbry_files:
|
||||
if l.sd_hash == sd:
|
||||
|
@ -1791,15 +1787,13 @@ class LBRYDaemon(jsonrpc.JSONRPC):
|
|||
for r in results:
|
||||
t = {}
|
||||
t.update(r[0])
|
||||
if 'name' in r[1].keys():
|
||||
r[1]['stream_name'] = r[1]['name']
|
||||
del r[1]['name']
|
||||
if not 'thumbnail' in r[1].keys():
|
||||
r[1]['thumbnail'] = "img/Free-speech-flag.svg"
|
||||
t.update(r[1])
|
||||
t['cost_est'] = r[2]
|
||||
if not 'thumbnail' in t.keys():
|
||||
t['thumbnail'] = "img/Free-speech-flag.svg"
|
||||
consolidated_results.append(t)
|
||||
# log.info(str(t))
|
||||
|
||||
return consolidated_results
|
||||
|
||||
log.info('[' + str(datetime.now()) + '] Search nametrie: ' + search)
|
||||
|
@ -1845,46 +1839,30 @@ class LBRYDaemon(jsonrpc.JSONRPC):
|
|||
|
||||
def jsonrpc_publish(self, p):
|
||||
"""
|
||||
Make a new name claim
|
||||
Make a new name claim and publish associated data to lbrynet
|
||||
|
||||
Args:
|
||||
'name': name to be claimed, string
|
||||
'file_path': path to file to be associated with name, string
|
||||
'bid': amount of credits to commit in this claim, float
|
||||
optional 'author': author, string
|
||||
optional 'title': title, description
|
||||
optional 'description': content description, string
|
||||
optional 'thumbnail': thumbnail image url
|
||||
optional 'key_fee': key fee to be paid to publisher, float (default 0.0)
|
||||
optional 'key_fee_address': address for key fee to be sent to, string (defaults on new address)
|
||||
optional 'content_license': content license string
|
||||
optional 'sources': alternative sources dict, keys 'lbry_sd_hash', 'btih', 'url'
|
||||
'metadata': metadata dictionary
|
||||
optional 'fee'
|
||||
Returns:
|
||||
Confirmation message
|
||||
Claim txid
|
||||
"""
|
||||
|
||||
metadata_fields = ["name", "file_path", "bid", "author", "title",
|
||||
"description", "thumbnail", "key_fee", "key_fee_address",
|
||||
"content_license", "sources"]
|
||||
|
||||
for k in metadata_fields:
|
||||
if k not in p.keys():
|
||||
p[k] = None
|
||||
# start(self, name, file_path, bid, metadata, fee=None, sources=None):
|
||||
name = p['name']
|
||||
bid = p['bid']
|
||||
file_path = p['file_path']
|
||||
metadata = p['metadata']
|
||||
if 'fee' in p:
|
||||
fee = p['fee']
|
||||
else:
|
||||
fee = None
|
||||
|
||||
pub = Publisher(self.session, self.lbry_file_manager, self.session.wallet)
|
||||
|
||||
d = pub.start(p['name'],
|
||||
p['file_path'],
|
||||
p['bid'],
|
||||
title=p['title'],
|
||||
description=p['description'],
|
||||
thumbnail=p['thumbnail'],
|
||||
key_fee=p['key_fee'],
|
||||
key_fee_address=p['key_fee_address'],
|
||||
content_license=p['content_license'],
|
||||
author=p['author'],
|
||||
sources=p['sources'])
|
||||
|
||||
d = pub.start(name, file_path, bid, metadata, fee)
|
||||
d.addCallbacks(lambda msg: self._render_response(msg, OK_CODE),
|
||||
lambda err: self._render_response(err.getTraceback(), BAD_REQUEST))
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ log.addHandler(handler)
|
|||
log.setLevel(logging.INFO)
|
||||
|
||||
class GetStream(object):
|
||||
def __init__(self, sd_identifier, session, wallet, lbry_file_manager, max_key_fee, pay_key=True, data_rate=0.5,
|
||||
def __init__(self, sd_identifier, session, wallet, lbry_file_manager, max_key_fee, data_rate=0.5,
|
||||
timeout=DEFAULT_TIMEOUT, download_directory=None, file_name=None):
|
||||
self.wallet = wallet
|
||||
self.resolved_name = None
|
||||
|
@ -50,7 +50,6 @@ class GetStream(object):
|
|||
self.key_fee = None
|
||||
self.key_fee_address = None
|
||||
self.data_rate = data_rate
|
||||
self.pay_key = pay_key
|
||||
self.name = None
|
||||
self.file_name = file_name
|
||||
self.session = session
|
||||
|
@ -79,7 +78,7 @@ class GetStream(object):
|
|||
self.finished.callback((self.stream_hash, self.download_path))
|
||||
|
||||
elif self.timeout_counter >= self.timeout:
|
||||
log.info("Timeout downloading lbry://" + self.resolved_name + ", " + str(self.stream_info))
|
||||
log.info("Timeout downloading lbry://%s" % self.resolved_name)
|
||||
self.checker.stop()
|
||||
self.d.cancel()
|
||||
self.code = STREAM_STAGES[4]
|
||||
|
@ -88,27 +87,23 @@ class GetStream(object):
|
|||
def start(self, stream_info, name):
|
||||
self.resolved_name = name
|
||||
self.stream_info = stream_info
|
||||
if 'stream_hash' in self.stream_info.keys():
|
||||
self.stream_hash = self.stream_info['stream_hash']
|
||||
elif 'sources' in self.stream_info.keys():
|
||||
if 'sources' in self.stream_info:
|
||||
self.stream_hash = self.stream_info['sources']['lbry_sd_hash']
|
||||
else:
|
||||
raise InvalidStreamInfoError(self.stream_info)
|
||||
if 'description' in self.stream_info.keys():
|
||||
if 'description' in self.stream_info:
|
||||
self.description = self.stream_info['description']
|
||||
if 'key_fee' in self.stream_info.keys():
|
||||
self.key_fee = float(self.stream_info['key_fee'])
|
||||
if 'key_fee_address' in self.stream_info.keys():
|
||||
self.key_fee_address = self.stream_info['key_fee_address']
|
||||
if 'fee' in self.stream_info:
|
||||
if 'LBC' in self.stream_info['fee']:
|
||||
self.key_fee = float(self.stream_info['fee']['LBC']['amount'])
|
||||
self.key_fee_address = self.stream_info['fee']['LBC']['address']
|
||||
else:
|
||||
self.key_fee_address = None
|
||||
else:
|
||||
self.key_fee = None
|
||||
self.key_fee_address = None
|
||||
if self.key_fee > self.max_key_fee:
|
||||
if self.pay_key:
|
||||
log.info("Key fee (" + str(self.key_fee) + ") above limit of " + str(
|
||||
self.max_key_fee) + ", didn't download lbry://" + str(self.resolved_name))
|
||||
log.info("Key fee %f above limit of %f didn't download lbry://%s" % (self.key_fee, self.max_key_fee, self.resolved_name))
|
||||
return defer.fail(None)
|
||||
else:
|
||||
pass
|
||||
|
@ -145,7 +140,7 @@ class GetStream(object):
|
|||
reserved_points = self.wallet.reserve_points(self.key_fee_address, self.key_fee)
|
||||
if reserved_points is None:
|
||||
return defer.fail(InsufficientFundsError())
|
||||
log.info("Key fee: " + str(self.key_fee) + " | " + str(self.key_fee_address))
|
||||
log.info("Key fee: %f --> %s" % (self.key_fee, self.key_fee_address))
|
||||
return self.wallet.send_points_to_address(reserved_points, self.key_fee)
|
||||
return defer.succeed(None)
|
||||
|
||||
|
@ -155,5 +150,5 @@ class GetStream(object):
|
|||
d = defer.Deferred()
|
||||
self.downloader = downloader
|
||||
self.download_path = os.path.join(downloader.download_directory, downloader.file_name)
|
||||
d.addCallback(lambda _: log.info("[" + str(datetime.now()) + "] Downloading " + str(self.stream_hash) + " --> " + str(self.download_path)))
|
||||
d.addCallback(lambda _: log.info("[%s] Downloading %s --> %s" % (datetime.now(), self.stream_hash, self.file_name)))
|
||||
d.addCallback(lambda _: self.downloader.start())
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
import mimetypes
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
@ -36,42 +37,27 @@ class Publisher(object):
|
|||
self.received_file_name = False
|
||||
self.file_path = None
|
||||
self.file_name = None
|
||||
self.thumbnail = None
|
||||
self.title = None
|
||||
self.publish_name = None
|
||||
self.bid_amount = None
|
||||
self.key_fee = None
|
||||
self.key_fee_address = None
|
||||
self.key_fee_address_chosen = False
|
||||
self.description = None
|
||||
self.verified = False
|
||||
self.lbry_file = None
|
||||
self.sd_hash = None
|
||||
self.tx_hash = None
|
||||
self.content_license = None
|
||||
self.author = None
|
||||
self.sources = None
|
||||
self.txid = None
|
||||
self.sources = {}
|
||||
self.fee = None
|
||||
|
||||
def start(self, name, file_path, bid, title=None, description=None, thumbnail=None,
|
||||
key_fee=None, key_fee_address=None, content_license=None, author=None, sources=None):
|
||||
def start(self, name, file_path, bid, metadata, fee=None, sources={}):
|
||||
|
||||
def _show_result():
|
||||
message = "[" + str(datetime.now()) + "] Published " + self.file_name + " --> lbry://" + \
|
||||
str(self.publish_name) + " with txid: " + str(self.tx_hash)
|
||||
|
||||
message = "[%s] Published %s --> lbry://%s txid: %s" % (datetime.now(), self.file_name, self.publish_name, self.txid)
|
||||
log.info(message)
|
||||
return defer.succeed(self.tx_hash)
|
||||
return defer.succeed(self.txid)
|
||||
|
||||
self.publish_name = name
|
||||
self.file_path = file_path
|
||||
self.bid_amount = bid
|
||||
self.title = title
|
||||
self.description = description
|
||||
self.thumbnail = thumbnail
|
||||
self.key_fee = key_fee
|
||||
self.key_fee_address = key_fee_address
|
||||
self.content_license = content_license
|
||||
self.author = author
|
||||
self.sources = sources
|
||||
self.fee = fee
|
||||
self.metadata = metadata
|
||||
|
||||
d = self._check_file_path(self.file_path)
|
||||
d.addCallback(lambda _: create_lbry_file(self.session, self.lbry_file_manager,
|
||||
|
@ -118,20 +104,21 @@ class Publisher(object):
|
|||
self.lbry_file.stream_hash)
|
||||
|
||||
def set_sd_hash(sd_hash):
|
||||
self.sd_hash = sd_hash
|
||||
self.sources['lbry_sd_hash'] = sd_hash
|
||||
|
||||
d.addCallback(set_sd_hash)
|
||||
return d
|
||||
|
||||
def _claim_name(self):
|
||||
d = self.wallet.claim_name(self.publish_name, self.sd_hash, self.bid_amount,
|
||||
description=self.description, key_fee=self.key_fee,
|
||||
key_fee_address=self.key_fee_address, thumbnail=self.thumbnail,
|
||||
content_license=self.content_license, author=self.author,
|
||||
sources=self.sources)
|
||||
|
||||
def set_tx_hash(tx_hash):
|
||||
self.tx_hash = tx_hash
|
||||
self.metadata['content-type'] = mimetypes.guess_type(os.path.join(self.lbry_file.download_directory,
|
||||
self.lbry_file.file_name))[0]
|
||||
d = self.wallet.claim_name(self.publish_name,
|
||||
self.bid_amount,
|
||||
self.sources,
|
||||
self.metadata,
|
||||
fee=self.fee)
|
||||
def set_tx_hash(txid):
|
||||
self.txid = txid
|
||||
|
||||
d.addCallback(set_tx_hash)
|
||||
return d
|
||||
|
|
Loading…
Reference in a new issue