Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repost with deletions/edits v1 #3687

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ idea:
cp -r scripts/idea/* .idea

elastic-docker:
docker run -d -v lbryhub:/usr/share/elasticsearch/data -p 9200:9200 -p 9300:9300 -e"ES_JAVA_OPTS=-Xms512m -Xmx512m" -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.12.1
docker run -d --env network.publish_host=127.0.0.1 -v lbryhub:/usr/share/elasticsearch/data -p 9200:9200 -p 9300:9300 -e"ES_JAVA_OPTS=-Xms512m -Xmx512m" -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.12.1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I seem to have to use this to get "make elastic-docker" to work. Is it just me? (MacOS aarch64)

13 changes: 12 additions & 1 deletion lbry/extras/daemon/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -3735,7 +3735,18 @@ async def jsonrpc_stream_update(
if old_txo.claim.is_stream:
claim.stream.update(file_path=file_path, **kwargs)
elif old_txo.claim.is_repost:
claim.repost.update(**kwargs)
reposted_txo = await self.ledger.get_claim_by_claim_id(
old_txo.claim.repost.reference.claim_id, include_is_my_output=True
)
assert reposted_txo
#log.error("%s", reposted_txo)
assert isinstance(reposted_txo, Output)
if not isinstance(reposted_txo, Output) or not reposted_txo.can_decode_claim:
raise InputValueError(
f"A claim with id '{reposted_txo.claim_id}' was found but could not be decoded."
)
assert isinstance(reposted_txo.claim, Claim)
claim.repost.update(claim_type=reposted_txo.claim.claim_type, **kwargs)

if clear_channel:
claim.clear_signature()
Expand Down
4 changes: 2 additions & 2 deletions lbry/schema/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
build:
rm types/v2/* -rf
rm -rf types/v2/*
touch types/v2/__init__.py
cd types/v2/ && protoc --python_out=. -I ../../../../../types/v2/proto/ ../../../../../types/v2/proto/*.proto
cd types/v2/ && cp ../../../../../types/jsonschema/* ./
sed -e 's/^import\ \(.*\)_pb2\ /from . import\ \1_pb2\ /g' -i types/v2/*.py
sed -e 's/^import\ \(.*\)_pb2\ /from . import\ \1_pb2\ /g' -i.bak types/v2/*.py
99 changes: 99 additions & 0 deletions lbry/schema/attrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
from lbry.constants import COIN
from lbry.error import MissingPublishedFileError, EmptyPublishedFileError

import lbry.schema.claim as claim
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 (
Claim as ClaimMessage,
Fee as FeeMessage,
Location as LocationMessage,
Language as LanguageMessage
Expand Down Expand Up @@ -353,6 +355,96 @@ class ClaimReference(Metadata):

__slots__ = ()

def _set_claim_type(self, claim_type: str = None):
"""select the appropriate member (stream, channel, repost, or collection)"""
def _set_message(m):
old_type = claim.Claim(m).claim_type
if old_type and claim_type is None:
m.ClearField(old_type)
return
member = getattr(m, claim_type)
member.SetInParent()
_set_message(self.message.deletions)
_set_message(self.message.edits)

def update(self, claim_type: str, **kwargs) -> dict:
self._set_claim_type(claim_type)
print(f'update: {kwargs.items()}')
clear1 = dict(filter(lambda i: i[0].startswith('clear_'), kwargs.items()))
clear2 = dict(map(lambda i: (i[0][len('clear_'):], i[1]), clear1.items()))
self.deletions.update(**clear2)
edits1 = dict(filter(lambda i: not i[0].startswith('clear_'), kwargs.items()))
return self.edits.update(**edits1)

def apply(self, reposted: 'claim.Claim'):
# This mapping converts the full field names produced by
# flatten(claim.to_dict()) to the short names utilized by
# claim.update().
# TODO: Complete this...
short_name = {
'source_size': 'file_size',
'source_sd_hash': 'sd_hash',
'source_bt_infohash': 'bt_infohash',
'source_file_name': 'file_name',
'source_file_hash': 'file_hash',
'image_width': 'width',
'video_width': 'width',
'image_height': 'height',
'video_height': 'height',
'video_duration': 'duration',
'video_audio_duration': 'duration',
'audio_duration': 'duration',
}
def flatten(field, d, out):
if isinstance(d, dict):
for k, v in d.items():
subfield = f'{field}_{k}' if field else k
flatten(subfield, v, out)
else:
# d is a leaf value
try:
out[short_name.get(field, field)] = int(d)
except (ValueError, TypeError):
out[short_name.get(field, field)] = d
m = ClaimMessage()
m.CopyFrom(reposted.message)
result = claim.Claim(m)
if self.has_deletions and self.deletions.claim_type == reposted.claim_type:
clear1 = dict([(f'clear_{k}', v) for k, v in self.deletions.to_dict().items()])
print(f'{reposted.claim_type} deletions: {clear1}')
clear2 = dict()
flatten('', clear1, clear2)
print(f'{reposted.claim_type} deletions: {clear2}')
attr = getattr(result, result.claim_type)
attr.update(**clear2)
if self.has_edits and self.edits.claim_type == reposted.claim_type:
edits1 = self.edits.to_dict()
print(f'{reposted.claim_type} edits: {edits1}')
edits2 = dict()
flatten('', edits1, edits2)
print(f'{reposted.claim_type} edits: {edits2}')
attr = getattr(result, result.claim_type)
attr.update(**edits2)
return result

@property
def has_deletions(self) -> bool:
return self.message.HasField('deletions')

@property
def deletions(self) -> 'claim.BaseClaim':
c = claim.Claim(self.message.deletions)
return getattr(c, c.claim_type)

@property
def has_edits(self) -> bool:
return self.message.HasField('edits')

@property
def edits(self) -> 'claim.BaseClaim':
c = claim.Claim(self.message.edits)
return getattr(c, c.claim_type)

@property
def claim_id(self) -> str:
return hexlify(self.claim_hash[::-1]).decode()
Expand Down Expand Up @@ -449,6 +541,13 @@ class LanguageList(BaseMessageList[Language]):
def append(self, value: str):
self.add().langtag = value

def remove(self, value: str) -> bool:
r = 0
for i, v in enumerate(self):
if v.langtag == value:
del self[i]
r += 1
return r > 0

class Location(Metadata):

Expand Down
46 changes: 40 additions & 6 deletions lbry/schema/claim.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def none_check(self, kwargs):
if value is None:
raise InputValueIsNoneError(key)

def update(self, **kwargs):
def update(self, strict_update=True, **kwargs) -> dict:
self.none_check(kwargs)

for key in list(kwargs):
Expand All @@ -136,8 +136,22 @@ def update(self, **kwargs):

for l in self.repeat_fields:
field = getattr(self, l)
if kwargs.pop(f'clear_{l}', False):
del field[:]
clear = kwargs.pop(f'clear_{l}', False)
if isinstance(clear, bool) and clear:
failed = []
if len(field) > 0:
del field[:]
else:
failed = clear
if failed:
kwargs[f'clear_{l}'] = failed
if isinstance(clear, list):
failed = []
for c in clear:
if not field.remove(c):
failed.append(c)
if failed:
kwargs[f'clear_{l}'] = failed
items = kwargs.pop(l, None)
if items is not None:
if isinstance(items, str):
Expand All @@ -147,8 +161,16 @@ def update(self, **kwargs):
else:
raise ValueError(f"Unknown {l} value: {items}")

failed = dict()
for key, value in kwargs.items():
setattr(self, key, value)
try:
setattr(self, key, value)
except AttributeError:
failed[key] = value
if strict_update:
raise

return failed

@property
def title(self) -> str:
Expand Down Expand Up @@ -213,7 +235,7 @@ def to_dict(self):
fee['amount'] = str(self.fee.amount)
return claim

def update(self, file_path=None, height=None, width=None, duration=None, **kwargs):
def update(self, file_path=None, height=None, width=None, duration=None, **kwargs) -> dict:

if kwargs.pop('clear_fee', False):
self.message.ClearField('fee')
Expand Down Expand Up @@ -264,7 +286,7 @@ def update(self, file_path=None, height=None, width=None, duration=None, **kwarg
media_args['width'] = width
media.update(**media_args)

super().update(**kwargs)
return super().update(**kwargs)

@property
def author(self) -> str:
Expand Down Expand Up @@ -398,6 +420,18 @@ class Repost(BaseClaim):

claim_type = Claim.REPOST

def update(self, **kwargs) -> dict:
claim_type = kwargs.pop('claim_type', None)
# Update common fields within BaseClaim.
kwargs = super().update(strict_update=False, **kwargs)
if claim_type:
# Remaining updates go into deletes/edits of ClaimReference.
kwargs = self.reference.update(claim_type, **kwargs)
return kwargs
Comment on lines +423 to +430
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See PR description. This is where I have a choice of applying the update to BaseClaim or stuff it inside ClaimReference.


def apply(self, reposted: 'Claim'):
return self.reference.apply(reposted)

@property
def reference(self) -> ClaimReference:
return ClaimReference(self.message)
Expand Down
2 changes: 1 addition & 1 deletion lbry/schema/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def message_to_txo(self, txo_message, tx_map):
if claim.HasField('channel'):
txo.channel = tx_map[claim.channel.tx_hash].outputs[claim.channel.nout]
if claim.HasField('repost'):
txo.reposted_claim = tx_map[claim.repost.tx_hash].outputs[claim.repost.nout]
txo.original_reposted_claim = tx_map[claim.repost.tx_hash].outputs[claim.repost.nout]
try:
if txo.claim.is_channel:
txo.meta['claims_in_channel'] = claim.claims_in_channel
Expand Down
4,729 changes: 49 additions & 4,680 deletions lbry/schema/types/v2/claim_pb2.py

Large diffs are not rendered by default.

66 changes: 11 additions & 55 deletions lbry/schema/types/v2/purchase_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading