Normalize tag names

This commit is contained in:
Miroslav Kovar 2019-09-25 12:28:02 +02:00 committed by Lex Berezhny
parent 98b9972fa5
commit db34f89251
5 changed files with 62 additions and 4 deletions

View file

@ -13,6 +13,7 @@ from torba.client.constants import COIN
from lbry.schema.mime_types import guess_media_type
from lbry.schema.base import Metadata, BaseMessageList
from lbry.schema.tags import clean_tags, normalize_tag
from lbry.schema.types.v2.claim_pb2 import (
Fee as FeeMessage,
Location as LocationMessage,
@ -533,3 +534,22 @@ class LocationList(BaseMessageList[Location]):
def append(self, value):
self.add().from_value(value)
class TagList(BaseMessageList[str]):
__slots__ = ()
item_class = str
def __init__(self, message):
message[:] = clean_tags(message)
self.message = message
def append(self, tag: str):
tag = normalize_tag(tag)
if tag not in self.message:
self.message.append(tag)
def extend(self, tags: List[str]):
tags = clean_tags(tags)
tags = list(set(tags).difference(set(self.message)))
self.message.extend(tags)

View file

@ -119,3 +119,6 @@ class BaseMessageList(Metadata, Generic[I]):
def __delitem__(self, key):
del self._message[key]
def __eq__(self, values: List[str]) -> bool:
return self._message == values

View file

@ -13,7 +13,7 @@ from lbry.schema.base import Signable
from lbry.schema.mime_types import guess_media_type, guess_stream_type
from lbry.schema.attrs import (
Source, Playable, Dimmensional, Fee, Image, Video, Audio,
LanguageList, LocationList, ClaimList, ClaimReference
LanguageList, LocationList, ClaimList, ClaimReference, TagList
)
from lbry.schema.types.v2.claim_pb2 import Claim as ClaimMessage
@ -164,8 +164,8 @@ class BaseClaim:
return Source(self.claim.message.thumbnail)
@property
def tags(self) -> List:
return self.claim.message.tags
def tags(self) -> List[str]:
return TagList(self.claim.message.tags)
@property
def languages(self) -> LanguageList:

View file

@ -523,6 +523,19 @@ class ChannelCommands(CommandTestCase):
self.assertEqual(result[0]['amount'], '3.0')
await self.channel_abandon(self.get_claim_id(channel))
async def test_tag_normalization(self):
tx1 = await self.channel_create('@abc', '1.0', tags=['aBc', ' ABC ', 'xYZ ', 'xyz'])
claim_id = self.get_claim_id(tx1)
self.assertCountEqual(tx1['outputs'][0]['value']['tags'], ['abc', 'xyz'])
tx2 = await self.channel_update(claim_id, tags=[' pqr', 'PQr '])
self.assertCountEqual(tx2['outputs'][0]['value']['tags'], ['abc', 'xyz', 'pqr'])
tx3 = await self.channel_update(claim_id, tags=' pqr')
self.assertCountEqual(tx3['outputs'][0]['value']['tags'], ['abc', 'xyz', 'pqr'])
tx4 = await self.channel_update(claim_id, tags=[' pqr', 'PQr '], clear_tags=True)
self.assertEqual(tx4['outputs'][0]['value']['tags'], ['pqr'])
class StreamCommands(ClaimTestCase):
@ -1101,13 +1114,14 @@ class StreamCommands(ClaimTestCase):
)
# publishing again clears channel
tx4 = await self.publish('foo', languages='uk-UA')
tx4 = await self.publish('foo', languages='uk-UA', tags=['Anime', 'anime '])
self.assertEqual(2, len(self.daemon.jsonrpc_file_list()))
r = await self.resolve('lbry://foo')
claim = r['lbry://foo']
self.assertEqual(claim['txid'], tx4['outputs'][0]['txid'])
self.assertNotIn('signing_channel', claim)
self.assertEqual(claim['value']['languages'], ['uk-UA'])
self.assertEqual(claim['value']['tags'], ['anime'])
class SupportCommands(CommandTestCase):

View file

@ -97,6 +97,27 @@ class TestLanguages(TestCase):
stream.languages.append('en-Zzz-US')
class TestTags(TestCase):
def test_normalize_tags(self):
claim = Claim()
claim.channel.update(tags=['Anime', 'anime', ' aNiMe', 'maNGA '])
self.assertCountEqual(claim.channel.tags, ['anime', 'manga'])
claim.channel.update(tags=['Juri', 'juRi'])
self.assertCountEqual(claim.channel.tags, ['anime', 'manga', 'juri'])
claim.channel.update(tags='Anime')
self.assertCountEqual(claim.channel.tags, ['anime', 'manga', 'juri'])
claim.channel.update(clear_tags=True)
self.assertEqual(len(claim.channel.tags), 0)
claim.channel.update(tags='Anime')
self.assertEqual(claim.channel.tags, ['anime'])
class TestLocations(TestCase):
def test_location_successful_parsing(self):