remove lbrynet.metadata

This commit is contained in:
Jack Robison 2017-05-29 16:38:08 -04:00
parent 7c18a4a8f7
commit 96927ec985
13 changed files with 28 additions and 685 deletions

View file

@ -14,6 +14,7 @@ at anytime.
### Changed ### Changed
* Do not catch base exception in API command resolve * Do not catch base exception in API command resolve
* Remove deprecated `lbrynet.metadata` and update what used it to instead use `lbryschema`
* *
### Fixed ### Fixed

View file

@ -45,6 +45,7 @@ class NegotiatedPaymentRateManager(object):
""" """
self.base = base self.base = base
self.min_blob_data_payment_rate = base.min_blob_data_payment_rate
self.points_paid = 0.0 self.points_paid = 0.0
self.blob_tracker = availability_tracker self.blob_tracker = availability_tracker
self.generous = generous if generous is not None else conf.settings['is_generous_host'] self.generous = generous if generous is not None else conf.settings['is_generous_host']

View file

@ -17,6 +17,7 @@ from twisted.python.failure import Failure
from lbryschema.claim import ClaimDict from lbryschema.claim import ClaimDict
from lbryschema.uri import parse_lbry_uri from lbryschema.uri import parse_lbry_uri
from lbryschema.error import URIParseError from lbryschema.error import URIParseError
from lbryschema.fee import Fee
# TODO: importing this when internet is disabled raises a socket.gaierror # TODO: importing this when internet is disabled raises a socket.gaierror
from lbryum.version import LBRYUM_VERSION from lbryum.version import LBRYUM_VERSION
@ -25,8 +26,6 @@ from lbrynet import conf, analytics
from lbrynet.conf import LBRYCRD_WALLET, LBRYUM_WALLET, PTC_WALLET 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.Metadata import verify_name_characters
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
@ -448,7 +447,7 @@ class Daemon(AuthJSONRPCServer):
isinstance(settings[key], setting_type) or isinstance(settings[key], setting_type) or
( (
key == "max_key_fee" and key == "max_key_fee" and
isinstance(FeeValidator(settings[key]).amount, setting_type) isinstance(Fee(settings[key]).amount, setting_type)
) )
) )
@ -686,7 +685,7 @@ class Daemon(AuthJSONRPCServer):
publisher = Publisher(self.session, self.lbry_file_manager, self.session.wallet, publisher = Publisher(self.session, self.lbry_file_manager, self.session.wallet,
certificate_id) certificate_id)
verify_name_characters(name) parse_lbry_uri(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:
@ -1596,7 +1595,7 @@ class Daemon(AuthJSONRPCServer):
name = resolved['name'] name = resolved['name']
claim_id = resolved['claim_id'] claim_id = resolved['claim_id']
stream_info = resolved['value'] stream_info = ClaimDict.load_dict(resolved['value'])
if claim_id in self.streams: if claim_id in self.streams:
log.info("Already waiting on lbry://%s to start downloading", name) log.info("Already waiting on lbry://%s to start downloading", name)

View file

@ -3,10 +3,10 @@ import os
from twisted.internet import defer, threads from twisted.internet import defer, threads
from twisted.internet.task import LoopingCall from twisted.internet.task import LoopingCall
from lbrynet.core import utils from lbryschema.fee import Fee
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.lbryfilemanager.EncryptedFileDownloader import ManagedEncryptedFileDownloaderFactory from lbrynet.lbryfilemanager.EncryptedFileDownloader import ManagedEncryptedFileDownloaderFactory
from lbrynet import conf from lbrynet import conf
@ -94,7 +94,7 @@ class GetStream(object):
log.info("Downloading stream descriptor blob (%i seconds)", self.timeout_counter) log.info("Downloading stream descriptor blob (%i seconds)", self.timeout_counter)
def convert_max_fee(self): def convert_max_fee(self):
max_fee = FeeValidator(self.max_key_fee) max_fee = Fee(self.max_key_fee)
if max_fee.currency_symbol == "LBC": if max_fee.currency_symbol == "LBC":
return max_fee.amount return max_fee.amount
return self.exchange_rate_manager.to_lbc(self.max_key_fee).amount return self.exchange_rate_manager.to_lbc(self.max_key_fee).amount
@ -104,15 +104,14 @@ class GetStream(object):
self.code = next(s for s in STREAM_STAGES if s[0] == status) self.code = next(s for s in STREAM_STAGES if s[0] == status)
def check_fee(self, fee): def check_fee(self, fee):
validated_fee = FeeValidator(fee)
max_key_fee = self.convert_max_fee() max_key_fee = self.convert_max_fee()
converted_fee = self.exchange_rate_manager.to_lbc(validated_fee).amount converted_fee = self.exchange_rate_manager.to_lbc(fee).amount
if converted_fee > self.wallet.get_balance(): if converted_fee > self.wallet.get_balance():
raise InsufficientFundsError('Unable to pay the key fee of %s' % converted_fee) raise InsufficientFundsError('Unable to pay the key fee of %s' % converted_fee)
if converted_fee > max_key_fee: if converted_fee > max_key_fee:
raise KeyFeeAboveMaxAllowed('Key fee %s above max allowed %s' % (converted_fee, raise KeyFeeAboveMaxAllowed('Key fee %s above max allowed %s' % (converted_fee,
max_key_fee)) max_key_fee))
return validated_fee return fee
def get_downloader_factory(self, factories): def get_downloader_factory(self, factories):
for factory in factories: for factory in factories:
@ -165,12 +164,12 @@ class GetStream(object):
self._running = True self._running = True
self.set_status(INITIALIZING_CODE, name) self.set_status(INITIALIZING_CODE, name)
self.sd_hash = utils.get_sd_hash(stream_info) self.sd_hash = stream_info.source_hash
if 'fee' in stream_info['stream']['metadata']: if stream_info.has_fee:
try: try:
fee = yield threads.deferToThread(self.check_fee, fee = yield threads.deferToThread(self.check_fee,
stream_info['stream']['metadata']['fee']) stream_info.source_fee)
except Exception as err: except Exception as err:
self._running = False self._running = False
self.finished_deferred.errback(err) self.finished_deferred.errback(err)

View file

@ -5,8 +5,9 @@ import json
from twisted.internet import defer, threads from twisted.internet import defer, threads
from twisted.internet.task import LoopingCall from twisted.internet.task import LoopingCall
from lbryschema.fee import Fee
from lbrynet import conf from lbrynet import conf
from lbrynet.metadata.Fee import FeeValidator
from lbrynet.core.Error import InvalidExchangeRateResponse from lbrynet.core.Error import InvalidExchangeRateResponse
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -203,14 +204,14 @@ class ExchangeRateManager(object):
def to_lbc(self, fee): def to_lbc(self, fee):
if fee is None: if fee is None:
return None return None
if not isinstance(fee, FeeValidator): if not isinstance(fee, Fee):
fee_in = FeeValidator(fee) fee_in = Fee(fee)
else: else:
fee_in = fee fee_in = fee
return FeeValidator({ return Fee({
'currency':fee_in.currency_symbol, 'currency':fee_in.currency,
'amount': self.convert_currency(fee_in.currency_symbol, "LBC", fee_in.amount), 'amount': self.convert_currency(fee_in.currency, "LBC", fee_in.amount),
'address': fee_in.address 'address': fee_in.address
}) })
@ -261,13 +262,13 @@ class DummyExchangeRateManager(object):
def to_lbc(self, fee): def to_lbc(self, fee):
if fee is None: if fee is None:
return None return None
if not isinstance(fee, FeeValidator): if not isinstance(fee, Fee):
fee_in = FeeValidator(fee) fee_in = Fee(fee)
else: else:
fee_in = fee fee_in = fee
return FeeValidator({ return Fee({
'currency':fee_in.currency_symbol, 'currency':fee_in.currency,
'amount': self.convert_currency(fee_in.currency_symbol, "LBC", fee_in.amount), 'amount': self.convert_currency(fee_in.currency, "LBC", fee_in.amount),
'address': fee_in.address 'address': fee_in.address
}) })

View file

@ -1,39 +0,0 @@
import logging
import fee_schemas
from lbrynet.metadata.StructuredDict import StructuredDict
log = logging.getLogger(__name__)
class FeeValidator(StructuredDict):
def __init__(self, fee):
self._versions = [
('0.0.1', fee_schemas.VER_001, None)
]
StructuredDict.__init__(self, fee, fee.get('ver', '0.0.1'))
self.currency_symbol = self['currency']
self.amount = self._get_amount()
self.address = self['address']
def _get_amount(self):
amt = self['amount']
try:
return float(amt)
except TypeError:
log.error('Failed to convert fee amount %s to float', amt)
raise
class LBCFeeValidator(StructuredDict):
pass
class BTCFeeValidator(StructuredDict):
pass
class USDFeeValidator(StructuredDict):
pass

View file

@ -1,44 +0,0 @@
import logging
from lbrynet.core import Error
from lbrynet.metadata.StructuredDict import StructuredDict
import metadata_schemas
log = logging.getLogger(__name__)
NAME_ALLOWED_CHARSET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0987654321-'
def verify_name_characters(name):
assert len(name) > 0, "Empty uri"
invalid_characters = {c for c in name if c not in NAME_ALLOWED_CHARSET}
if invalid_characters:
raise Error.InvalidName(name, invalid_characters)
return True
def migrate_001_to_002(metadata):
metadata['ver'] = '0.0.2'
metadata['nsfw'] = False
def migrate_002_to_003(metadata):
metadata['ver'] = '0.0.3'
if 'content-type' in metadata:
metadata['content_type'] = metadata['content-type']
del metadata['content-type']
class Metadata(StructuredDict):
current_version = '0.0.3'
_versions = [
('0.0.1', metadata_schemas.VER_001, None),
('0.0.2', metadata_schemas.VER_002, migrate_001_to_002),
('0.0.3', metadata_schemas.VER_003, migrate_002_to_003)
]
def __init__(self, metadata, migrate=True, target_version=None):
if not isinstance(metadata, dict):
raise TypeError("{} is not a dictionary".format(metadata))
starting_version = metadata.get('ver', '0.0.1')
StructuredDict.__init__(self, metadata, starting_version, migrate, target_version)

View file

@ -1,64 +0,0 @@
import jsonschema
import logging
from jsonschema import ValidationError
log = logging.getLogger(__name__)
class StructuredDict(dict):
"""
A dictionary that enforces a structure specified by a schema, and supports
migration between different versions of the schema.
"""
# To be specified in sub-classes, an array in the format
# [(version, schema, migration), ...]
_versions = []
# Used internally to allow schema lookups by version number
_schemas = {}
version = None
def __init__(self, value, starting_version, migrate=True, target_version=None):
dict.__init__(self, value)
self.version = starting_version
self._schemas = dict([(version, schema) for (version, schema, _) in self._versions])
self.validate(starting_version)
if migrate:
self.migrate(target_version)
def _upgrade_version_range(self, start_version, end_version):
after_starting_version = False
for version, schema, migration in self._versions:
if not after_starting_version:
if version == self.version:
after_starting_version = True
continue
yield version, schema, migration
if end_version and version == end_version:
break
def validate(self, version):
jsonschema.validate(self, self._schemas[version])
def migrate(self, target_version=None):
if target_version:
assert self._versions.index(target_version) > self.versions.index(self.version), \
"Current version is above target version"
for version, schema, migration in self._upgrade_version_range(self.version, target_version):
migration(self)
try:
self.validate(version)
except ValidationError as e:
raise ValidationError(
"Could not migrate to version %s due to validation error: %s" %
(version, e.message))
self.version = version

View file

@ -1,16 +0,0 @@
VER_001 = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'LBRY fee schema 0.0.1',
'type': 'object',
'properties': {
'amount': {
'type': 'number',
'minimum': 0,
'exclusiveMinimum': True,
},
'address': {
'type': 'string'
}
},
}

View file

@ -1,276 +0,0 @@
VER_001 = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'LBRY metadata schema 0.0.1',
'definitions': {
'fee_info': {
'type': 'object',
'properties': {
'amount': {
'type': 'number',
'minimum': 0,
'exclusiveMinimum': True,
},
'address': {
'type': 'string'
}
},
}
},
'type': 'object',
'properties': {
'ver': {
'type': 'string',
'default': '0.0.1'
},
'title': {
'type': 'string'
},
'description': {
'type': 'string'
},
'author': {
'type': 'string'
},
'language': {
'type': 'string'
},
'license': {
'type': 'string'
},
'content-type': {
'type': 'string'
},
'sources': {
'type': 'object',
'properties': {
'lbry_sd_hash': {
'type': 'string'
},
'btih': {
'type': 'string'
},
'url': {
'type': 'string'
}
},
'additionalProperties': False
},
'thumbnail': {
'type': 'string'
},
'preview': {
'type': 'string'
},
'fee': {
'properties': {
'LBC': {'$ref': '#/definitions/fee_info'},
'BTC': {'$ref': '#/definitions/fee_info'},
'USD': {'$ref': '#/definitions/fee_info'}
}
},
'contact': {
'type': 'number'
},
'pubkey': {
'type': 'string'
},
},
'required': [
'title', 'description', 'author', 'language', 'license', 'content-type', 'sources'],
'additionalProperties': False
}
VER_002 = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'LBRY metadata schema 0.0.2',
'definitions': {
'fee_info': {
'type': 'object',
'properties': {
'amount': {
'type': 'number',
'minimum': 0,
'exclusiveMinimum': True,
},
'address': {
'type': 'string'
}
},
}
},
'type': 'object',
'properties': {
'ver': {
'type': 'string',
'enum': ['0.0.2'],
},
'title': {
'type': 'string'
},
'description': {
'type': 'string'
},
'author': {
'type': 'string'
},
'language': {
'type': 'string'
},
'license': {
'type': 'string'
},
'content-type': {
'type': 'string'
},
'sources': {
'type': 'object',
'properties': {
'lbry_sd_hash': {
'type': 'string'
},
'btih': {
'type': 'string'
},
'url': {
'type': 'string'
}
},
'additionalProperties': False
},
'thumbnail': {
'type': 'string'
},
'preview': {
'type': 'string'
},
'fee': {
'properties': {
'LBC': {'$ref': '#/definitions/fee_info'},
'BTC': {'$ref': '#/definitions/fee_info'},
'USD': {'$ref': '#/definitions/fee_info'}
}
},
'contact': {
'type': 'number'
},
'pubkey': {
'type': 'string'
},
'license_url': {
'type': 'string'
},
'nsfw': {
'type': 'boolean',
'default': False
},
},
'required': [
'ver', 'title', 'description', 'author', 'language', 'license',
'content-type', 'sources', 'nsfw'
],
'additionalProperties': False
}
VER_003 = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'LBRY metadata schema 0.0.3',
'definitions': {
'fee_info': {
'type': 'object',
'properties': {
'amount': {
'type': 'number',
'minimum': 0,
'exclusiveMinimum': True,
},
'address': {
'type': 'string'
}
},
}
},
'type': 'object',
'properties': {
'ver': {
'type': 'string',
'enum': ['0.0.3'],
},
'title': {
'type': 'string'
},
'description': {
'type': 'string'
},
'author': {
'type': 'string'
},
'language': {
'type': 'string'
},
'license': {
'type': 'string'
},
'content_type': {
'type': 'string'
},
'sources': {
'type': 'object',
'properties': {
'lbry_sd_hash': {
'type': 'string'
},
'btih': {
'type': 'string'
},
'url': {
'type': 'string'
}
},
'additionalProperties': False
},
'thumbnail': {
'type': 'string'
},
'preview': {
'type': 'string'
},
'fee': {
'properties': {
'LBC': {'$ref': '#/definitions/fee_info'},
'BTC': {'$ref': '#/definitions/fee_info'},
'USD': {'$ref': '#/definitions/fee_info'}
}
},
'contact': {
'type': 'number'
},
'pubkey': {
'type': 'string'
},
'license_url': {
'type': 'string'
},
'nsfw': {
'type': 'boolean',
'default': False
},
'sig': {
'type': 'string'
}
},
'required': [
'ver', 'title', 'description', 'author', 'language', 'license',
'content_type', 'sources', 'nsfw'
],
'additionalProperties': False,
'dependencies': {
'pubkey': ['sig'],
'sig': ['pubkey']
}
}

View file

@ -1,218 +0,0 @@
from twisted.trial import unittest
from jsonschema import ValidationError
from lbrynet.core import Error
from lbrynet.metadata import Metadata
class MetadataTest(unittest.TestCase):
def test_name_error_if_blank(self):
with self.assertRaises(AssertionError):
Metadata.verify_name_characters("")
def test_name_error_if_contains_bad_chrs(self):
with self.assertRaises(Error.InvalidName):
Metadata.verify_name_characters("wu tang")
with self.assertRaises(Error.InvalidName):
Metadata.verify_name_characters("$wutang")
with self.assertRaises(Error.InvalidName):
Metadata.verify_name_characters("#wutang")
def test_validation_error_if_no_metadata(self):
metadata = {}
with self.assertRaises(ValidationError):
Metadata.Metadata(metadata)
def test_validation_error_if_source_is_missing(self):
metadata = {
'license': 'Oscilloscope Laboratories',
'description': 'Four couples meet for Sunday brunch only to discover they are stuck in a house together as the world may be about to end.',
'language': 'en',
'title': "It's a Disaster",
'author': 'Written and directed by Todd Berger',
'content-type': 'audio/mpeg',
'thumbnail': 'http://ia.media-imdb.com/images/M/MV5BMTQwNjYzMTQ0Ml5BMl5BanBnXkFtZTcwNDUzODM5Nw@@._V1_SY1000_CR0,0,673,1000_AL_.jpg',
}
with self.assertRaises(ValidationError):
Metadata.Metadata(metadata)
def test_metadata_works_without_fee(self):
metadata = {
'license': 'Oscilloscope Laboratories',
'description': 'Four couples meet for Sunday brunch only to discover they are stuck in a house together as the world may be about to end.',
'language': 'en',
'title': "It's a Disaster",
'author': 'Written and directed by Todd Berger',
'sources': {
'lbry_sd_hash': '8d0d6ea64d09f5aa90faf5807d8a761c32a27047861e06f81f41e35623a348a4b0104052161d5f89cf190f9672bc4ead'},
'content-type': 'audio/mpeg',
'thumbnail': 'http://ia.media-imdb.com/images/M/MV5BMTQwNjYzMTQ0Ml5BMl5BanBnXkFtZTcwNDUzODM5Nw@@._V1_SY1000_CR0,0,673,1000_AL_.jpg',
}
m = Metadata.Metadata(metadata)
self.assertFalse('fee' in m)
def test_validation_error_if_invalid_source(self):
metadata = {
'license': 'Oscilloscope Laboratories',
'description': 'Four couples meet for Sunday brunch only to discover they are stuck in a house together as the world may be about to end.',
'language': 'en',
'title': "It's a Disaster",
'author': 'Written and directed by Todd Berger',
'sources': {
'fake': 'source'},
'content-type': 'audio/mpeg',
'thumbnail': 'http://ia.media-imdb.com/images/M/MV5BMTQwNjYzMTQ0Ml5BMl5BanBnXkFtZTcwNDUzODM5Nw@@._V1_SY1000_CR0,0,673,1000_AL_.jpg',
}
with self.assertRaises(ValidationError):
Metadata.Metadata(metadata)
def test_validation_error_if_missing_v001_field(self):
metadata = {
'license': 'Oscilloscope Laboratories',
'fee': {'LBC': {'amount': 50.0, 'address': 'bRQJASJrDbFZVAvcpv3NoNWoH74LQd5JNV'}},
'description': 'Four couples meet for Sunday brunch only to discover they are stuck in a house together as the world may be about to end.',
'language': 'en',
'author': 'Written and directed by Todd Berger',
'sources': {
'lbry_sd_hash': '8d0d6ea64d09f5aa90faf5807d8a761c32a27047861e06f81f41e35623a348a4b0104052161d5f89cf190f9672bc4ead'},
'content-type': 'audio/mpeg',
'thumbnail': 'http://ia.media-imdb.com/images/M/MV5BMTQwNjYzMTQ0Ml5BMl5BanBnXkFtZTcwNDUzODM5Nw@@._V1_SY1000_CR0,0,673,1000_AL_.jpg'
}
with self.assertRaises(ValidationError):
Metadata.Metadata(metadata)
def test_version_is_001_if_all_fields_are_present(self):
metadata = {
'license': 'Oscilloscope Laboratories',
'description': 'Four couples meet for Sunday brunch only to discover they are stuck in a house together as the world may be about to end.',
'language': 'en',
'title': "It's a Disaster",
'author': 'Written and directed by Todd Berger',
'sources': {
'lbry_sd_hash': '8d0d6ea64d09f5aa90faf5807d8a761c32a27047861e06f81f41e35623a348a4b0104052161d5f89cf190f9672bc4ead'},
'content-type': 'audio/mpeg',
'thumbnail': 'http://ia.media-imdb.com/images/M/MV5BMTQwNjYzMTQ0Ml5BMl5BanBnXkFtZTcwNDUzODM5Nw@@._V1_SY1000_CR0,0,673,1000_AL_.jpg',
}
m = Metadata.Metadata(metadata, migrate=False)
self.assertEquals('0.0.1', m.version)
def test_validation_error_if_there_is_an_extra_field(self):
metadata = {
'license': 'Oscilloscope Laboratories',
'description': 'Four couples meet for Sunday brunch only to discover they are stuck in a house together as the world may be about to end.',
'language': 'en',
'title': "It's a Disaster",
'author': 'Written and directed by Todd Berger',
'sources': {
'lbry_sd_hash': '8d0d6ea64d09f5aa90faf5807d8a761c32a27047861e06f81f41e35623a348a4b0104052161d5f89cf190f9672bc4ead'},
'content-type': 'audio/mpeg',
'thumbnail': 'http://ia.media-imdb.com/images/M/MV5BMTQwNjYzMTQ0Ml5BMl5BanBnXkFtZTcwNDUzODM5Nw@@._V1_SY1000_CR0,0,673,1000_AL_.jpg',
'MYSTERYFIELD': '?'
}
with self.assertRaises(ValidationError):
Metadata.Metadata(metadata, migrate=False)
def test_version_is_002_if_all_fields_are_present(self):
metadata = {
'license': 'NASA',
'fee': {'USD': {'amount': 0.01, 'address': 'baBYSK7CqGSn5KrEmNmmQwAhBSFgo6v47z'}},
'ver': '0.0.2',
'description': 'SDO captures images of the sun in 10 different wavelengths, each of which helps highlight a different temperature of solar material. Different temperatures can, in turn, show specific structures on the sun such as solar flares, which are gigantic explosions of light and x-rays, or coronal loops, which are stream of solar material travelling up and down looping magnetic field lines',
'language': 'en',
'author': 'The SDO Team, Genna Duberstein and Scott Wiessinger',
'title': 'Thermonuclear Art',
'sources': {
'lbry_sd_hash': '8655f713819344980a9a0d67b198344e2c462c90f813e86f0c63789ab0868031f25c54d0bb31af6658e997e2041806eb'},
'nsfw': False,
'content-type': 'video/mp4',
'thumbnail': 'https://svs.gsfc.nasa.gov/vis/a010000/a012000/a012034/Combined.00_08_16_17.Still004.jpg'
}
m = Metadata.Metadata(metadata, migrate=False)
self.assertEquals('0.0.2', m.version)
def test_version_is_003_if_all_fields_are_present(self):
metadata = {
'license': 'NASA',
'fee': {'USD': {'amount': 0.01, 'address': 'baBYSK7CqGSn5KrEmNmmQwAhBSFgo6v47z'}},
'ver': '0.0.3',
'description': 'SDO captures images of the sun in 10 different wavelengths, each of which helps highlight a different temperature of solar material. Different temperatures can, in turn, show specific structures on the sun such as solar flares, which are gigantic explosions of light and x-rays, or coronal loops, which are stream of solar material travelling up and down looping magnetic field lines',
'language': 'en',
'author': 'The SDO Team, Genna Duberstein and Scott Wiessinger',
'title': 'Thermonuclear Art',
'sources': {
'lbry_sd_hash': '8655f713819344980a9a0d67b198344e2c462c90f813e86f0c63789ab0868031f25c54d0bb31af6658e997e2041806eb'},
'nsfw': False,
'content_type': 'video/mp4',
'thumbnail': 'https://svs.gsfc.nasa.gov/vis/a010000/a012000/a012034/Combined.00_08_16_17.Still004.jpg'
}
m = Metadata.Metadata(metadata, migrate=False)
self.assertEquals('0.0.3', m.version)
def test_version_claimed_is_001_but_version_is_002(self):
metadata = {
'license': 'NASA',
'fee': {'USD': {'amount': 0.01, 'address': 'baBYSK7CqGSn5KrEmNmmQwAhBSFgo6v47z'}},
'ver': '0.0.1',
'description': 'SDO captures images of the sun in 10 different wavelengths, each of which helps highlight a different temperature of solar material. Different temperatures can, in turn, show specific structures on the sun such as solar flares, which are gigantic explosions of light and x-rays, or coronal loops, which are stream of solar material travelling up and down looping magnetic field lines',
'language': 'en',
'author': 'The SDO Team, Genna Duberstein and Scott Wiessinger',
'title': 'Thermonuclear Art',
'sources': {
'lbry_sd_hash': '8655f713819344980a9a0d67b198344e2c462c90f813e86f0c63789ab0868031f25c54d0bb31af6658e997e2041806eb'},
'nsfw': False,
'content-type': 'video/mp4',
'thumbnail': 'https://svs.gsfc.nasa.gov/vis/a010000/a012000/a012034/Combined.00_08_16_17.Still004.jpg'
}
with self.assertRaises(ValidationError):
Metadata.Metadata(metadata, migrate=False)
def test_version_claimed_is_002_but_version_is_003(self):
metadata = {
'license': 'NASA',
'fee': {'USD': {'amount': 0.01, 'address': 'baBYSK7CqGSn5KrEmNmmQwAhBSFgo6v47z'}},
'ver': '0.0.2',
'description': 'SDO captures images of the sun in 10 different wavelengths, each of which helps highlight a different temperature of solar material. Different temperatures can, in turn, show specific structures on the sun such as solar flares, which are gigantic explosions of light and x-rays, or coronal loops, which are stream of solar material travelling up and down looping magnetic field lines',
'language': 'en',
'author': 'The SDO Team, Genna Duberstein and Scott Wiessinger',
'title': 'Thermonuclear Art',
'sources': {
'lbry_sd_hash': '8655f713819344980a9a0d67b198344e2c462c90f813e86f0c63789ab0868031f25c54d0bb31af6658e997e2041806eb'},
'nsfw': False,
'content_type': 'video/mp4',
'thumbnail': 'https://svs.gsfc.nasa.gov/vis/a010000/a012000/a012034/Combined.00_08_16_17.Still004.jpg'
}
with self.assertRaises(ValidationError):
Metadata.Metadata(metadata, migrate=False)
def test_version_001_ports_to_003(self):
metadata = {
'license': 'Oscilloscope Laboratories',
'description': 'Four couples meet for Sunday brunch only to discover they are stuck in a house together as the world may be about to end.',
'language': 'en',
'title': "It's a Disaster",
'author': 'Written and directed by Todd Berger',
'sources': {
'lbry_sd_hash': '8d0d6ea64d09f5aa90faf5807d8a761c32a27047861e06f81f41e35623a348a4b0104052161d5f89cf190f9672bc4ead'},
'content-type': 'audio/mpeg',
'thumbnail': 'http://ia.media-imdb.com/images/M/MV5BMTQwNjYzMTQ0Ml5BMl5BanBnXkFtZTcwNDUzODM5Nw@@._V1_SY1000_CR0,0,673,1000_AL_.jpg',
}
m = Metadata.Metadata(metadata, migrate=True)
self.assertEquals('0.0.3', m.version)
def test_version_002_ports_to_003(self):
metadata = {
'license': 'NASA',
'fee': {'USD': {'amount': 0.01, 'address': 'baBYSK7CqGSn5KrEmNmmQwAhBSFgo6v47z'}},
'ver': '0.0.2',
'description': 'SDO captures images of the sun in 10 different wavelengths, each of which helps highlight a different temperature of solar material. Different temperatures can, in turn, show specific structures on the sun such as solar flares, which are gigantic explosions of light and x-rays, or coronal loops, which are stream of solar material travelling up and down looping magnetic field lines',
'language': 'en',
'author': 'The SDO Team, Genna Duberstein and Scott Wiessinger',
'title': 'Thermonuclear Art',
'sources': {
'lbry_sd_hash': '8655f713819344980a9a0d67b198344e2c462c90f813e86f0c63789ab0868031f25c54d0bb31af6658e997e2041806eb'},
'nsfw': False,
'content-type': 'video/mp4',
'thumbnail': 'https://svs.gsfc.nasa.gov/vis/a010000/a012000/a012034/Combined.00_08_16_17.Still004.jpg'
}
m = Metadata.Metadata(metadata, migrate=True)
self.assertEquals('0.0.3', m.version)

View file

@ -1,6 +1,5 @@
from lbrynet.metadata import Fee from lbryschema.fee import Fee
from lbrynet.lbrynet_daemon import ExchangeRateManager from lbrynet.lbrynet_daemon import ExchangeRateManager
from lbrynet import conf
from lbrynet.core.Error import InvalidExchangeRateResponse from lbrynet.core.Error import InvalidExchangeRateResponse
from twisted.trial import unittest from twisted.trial import unittest
@ -15,7 +14,7 @@ class FeeFormatTest(unittest.TestCase):
'amount': 10.0, 'amount': 10.0,
'address': "bRcHraa8bYJZL7vkh5sNmGwPDERFUjGPP9" 'address': "bRcHraa8bYJZL7vkh5sNmGwPDERFUjGPP9"
} }
fee = Fee.FeeValidator(fee_dict) fee = Fee(fee_dict)
self.assertEqual(10.0, fee['amount']) self.assertEqual(10.0, fee['amount'])
self.assertEqual('USD', fee['currency']) self.assertEqual('USD', fee['currency'])