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

Add CONTENT_ITEM relation #7445

Merged
merged 2 commits into from
May 30, 2023
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from tribler.core.components.knowledge.db.knowledge_db import Operation, ResourceType

VALID_TAGS = [
'nl',
'tag',
'Tag',
'Тэг',
Expand All @@ -13,7 +14,7 @@

INVALID_TAGS = [
'',
'ta', # less than 3
't',
't' * 51, # more than 50
]

Expand Down
1 change: 1 addition & 0 deletions src/tribler/core/components/knowledge/db/knowledge_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class ResourceType(IntEnum):
# this is a section for extra types
TAG = 101
TORRENT = 102
CONTENT_ITEM = 103


@dataclass
Expand Down
24 changes: 13 additions & 11 deletions src/tribler/core/components/knowledge/db/tests/test_knowledge_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,24 +539,26 @@ def test_get_subjects(self):
self.db,
{
'infohash1': [
Resource(predicate=ResourceType.TITLE, name='ubuntu', auto_generated=True),
Resource(predicate=ResourceType.CONTENT_ITEM, name='ubuntu', auto_generated=True),
Resource(predicate=ResourceType.TAG, name='linux', auto_generated=True),
],
'infohash2': [
Resource(predicate=ResourceType.TITLE, name='ubuntu', auto_generated=True),
Resource(predicate=ResourceType.CONTENT_ITEM, name='ubuntu', auto_generated=True),
Resource(predicate=ResourceType.TAG, name='linux', auto_generated=True),
],
'infohash3': [
Resource(predicate=ResourceType.TITLE, name='debian', auto_generated=True),
Resource(predicate=ResourceType.CONTENT_ITEM, name='debian', auto_generated=True),
Resource(predicate=ResourceType.TAG, name='linux', auto_generated=True),
],
}
)

actual = self.db.get_subjects(subject_type=ResourceType.TORRENT, predicate=ResourceType.TITLE, obj='missed')
actual = self.db.get_subjects(subject_type=ResourceType.TORRENT, predicate=ResourceType.CONTENT_ITEM,
obj='missed')
assert actual == []

actual = self.db.get_subjects(subject_type=ResourceType.TORRENT, predicate=ResourceType.TITLE, obj='ubuntu')
actual = self.db.get_subjects(subject_type=ResourceType.TORRENT, predicate=ResourceType.CONTENT_ITEM,
obj='ubuntu')
assert actual == ['infohash1', 'infohash2']

actual = self.db.get_subjects(subject_type=ResourceType.TORRENT, predicate=ResourceType.TAG, obj='linux')
Expand All @@ -568,11 +570,11 @@ def test_get_statements(self):
self.db,
{
'infohash1': [
Resource(predicate=ResourceType.TITLE, name='ubuntu', auto_generated=True),
Resource(predicate=ResourceType.CONTENT_ITEM, name='ubuntu', auto_generated=True),
Resource(predicate=ResourceType.TYPE, name='linux', auto_generated=True),
],
'infohash2': [
Resource(predicate=ResourceType.TITLE, name='debian', auto_generated=True),
Resource(predicate=ResourceType.CONTENT_ITEM, name='debian', auto_generated=True),
Resource(predicate=ResourceType.TYPE, name='linux', auto_generated=True),
],
'INFOHASH1': [
Expand All @@ -582,7 +584,7 @@ def test_get_statements(self):
)

expected = [
SimpleStatement(subject_type=ResourceType.TORRENT, subject='infohash1', predicate=ResourceType.TITLE,
SimpleStatement(subject_type=ResourceType.TORRENT, subject='infohash1', predicate=ResourceType.CONTENT_ITEM,
object='ubuntu'),
SimpleStatement(subject_type=ResourceType.TORRENT, subject='infohash1', predicate=ResourceType.TYPE,
object='linux')
Expand All @@ -600,11 +602,11 @@ def test_various_queries(self):
self.db,
{
'infohash1': [
Resource(predicate=ResourceType.TITLE, name='ubuntu'),
Resource(predicate=ResourceType.CONTENT_ITEM, name='ubuntu'),
Resource(predicate=ResourceType.TYPE, name='linux'),
],
'infohash2': [
Resource(predicate=ResourceType.TITLE, name='debian'),
Resource(predicate=ResourceType.CONTENT_ITEM, name='debian'),
Resource(predicate=ResourceType.TYPE, name='linux'),
],
'infohash3': [
Expand Down Expand Up @@ -632,7 +634,7 @@ def _subjects(subject_type=None, obj='', predicate=None):

assert _subjects(obj='linux') == {'infohash1', 'infohash2', 'infohash3'}
assert _subjects(predicate=ResourceType.TAG, obj='linux') == {'infohash3'}
assert _subjects(predicate=ResourceType.TITLE) == {'infohash1', 'infohash2'}
assert _subjects(predicate=ResourceType.CONTENT_ITEM) == {'infohash1', 'infohash2'}

@db_session
def test_non_existent_misc(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
MIN_RESOURCE_LENGTH = 3
MIN_RESOURCE_LENGTH = 2
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change is necessary for the language statements transfer (nl, ru, en)

MAX_RESOURCE_LENGTH = 50
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

from tribler.core.components.knowledge.community.knowledge_community import KnowledgeCommunity
from tribler.core.components.knowledge.community.knowledge_payload import StatementOperation
from tribler.core.components.knowledge.community.knowledge_validator import is_valid_resource
from tribler.core.components.knowledge.db.knowledge_db import KnowledgeDatabase, Operation, ResourceType
from tribler.core.components.knowledge.knowledge_constants import MAX_RESOURCE_LENGTH, MIN_RESOURCE_LENGTH
from tribler.core.components.restapi.rest.rest_endpoint import HTTP_BAD_REQUEST, RESTEndpoint, RESTResponse
from tribler.core.components.restapi.rest.schema import HandledErrorSchema
from tribler.core.utilities.utilities import froze_it
Expand Down Expand Up @@ -65,24 +65,21 @@ async def update_knowledge_entries(self, request):
return error_response

# Validate whether the size of the tag is within the allowed range and filter out duplicate tags.
tags = set()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This set() is unnecessary here because statements anyway will be converted to sets later.

statements = []
self._logger.info(f'Statements about {infohash}: {params["statements"]}')
for statement in params["statements"]:
obj = statement["object"]
if statement["predicate"] == ResourceType.TAG and \
(len(obj) < MIN_RESOURCE_LENGTH or len(obj) > MAX_RESOURCE_LENGTH):
if not is_valid_resource(obj):
return RESTResponse({"error": "Invalid tag length"}, status=HTTP_BAD_REQUEST)

if obj not in tags:
tags.add(obj)
statements.append(statement)
statements.append(statement)

self.modify_statements(infohash, statements)

return RESTResponse({"success": True})

@db_session
def modify_statements(self, infohash: str, statements):
def modify_statements(self, infohash: str, statements: list):
"""
Modify the statements of a particular content item.
"""
Expand All @@ -92,7 +89,9 @@ def modify_statements(self, infohash: str, statements):
# First, get the current statements and compute the diff between the old and new statements
old_statements = self.db.get_statements(subject_type=ResourceType.TORRENT, subject=infohash)
old_statements = {(stmt.predicate, stmt.object) for stmt in old_statements}
self._logger.info(f'Old statements: {old_statements}')
new_statements = {(stmt["predicate"], stmt["object"]) for stmt in statements}
self._logger.info(f'New statements: {new_statements}')
added_statements = new_statements - old_statements
removed_statements = old_statements - new_statements

Expand All @@ -109,6 +108,9 @@ def modify_statements(self, infohash: str, statements):
signature = self.community.sign(operation)
self.db.add_operation(operation, signature, is_local_peer=True)

self._logger.info(f'Added statements: {added_statements}')
self._logger.info(f'Removed statements: {removed_statements}')

@docs(
tags=["General"],
summary="Get tag suggestions for a torrent with a particular infohash.",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import logging
import queue
import time
from asyncio import Event
from dataclasses import dataclass
from typing import Optional, Set

Expand Down Expand Up @@ -187,8 +186,8 @@ async def process_torrent_title(self, infohash: Optional[bytes] = None, title: O
objects=tags)

if content_items := set(extract_only_valid_tags(title, rules=content_items_rules)):
self.save_statements(subject_type=ResourceType.TORRENT, subject=infohash_str, predicate=ResourceType.TITLE,
objects=content_items)
self.save_statements(subject_type=ResourceType.TORRENT, subject=infohash_str,
predicate=ResourceType.CONTENT_ITEM, objects=content_items)

return len(tags) + len(content_items)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

def test_extract_only_valid_tags():
# test that extract_only_valid_tags extracts only valid tags
assert set(extract_only_valid_tags('[valid-tag, in va li d]', rules=general_rules)) == {'valid-tag'}
assert set(extract_only_valid_tags('[valid-tag, i n v a l i d]', rules=general_rules)) == {'valid-tag'}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def build_snippets(self, search_results: List[Dict]) -> List[Dict]:
with db_session:
content_items: List[str] = self.knowledge_db.get_objects(subject_type=ResourceType.TORRENT,
subject=search_result["infohash"],
predicate=ResourceType.TITLE)
predicate=ResourceType.CONTENT_ITEM)
if content_items:
for content_id in content_items:
content_to_torrents[content_id].append(search_result)
Expand Down
7 changes: 6 additions & 1 deletion src/tribler/gui/dialogs/editmetadatadialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@
from tribler.gui.utilities import connect, get_objects_with_predicate, get_ui_file_path, tr
from tribler.gui.widgets.tagbutton import TagButton

METADATA_TABLE_PREDICATES = [ResourceType.TITLE, ResourceType.DESCRIPTION, ResourceType.DATE, ResourceType.LANGUAGE]
METADATA_TABLE_PREDICATES = [
ResourceType.CONTENT_ITEM,
ResourceType.DESCRIPTION,
ResourceType.DATE,
ResourceType.LANGUAGE
]


class EditMetadataDialog(DialogContainer):
Expand Down
2 changes: 1 addition & 1 deletion src/tribler/gui/qt_resources/edit_metadata_dialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ margin: 0px;
</column>
<item>
<property name="text">
<string>Title</string>
<string>Content Item</string>
</property>
</item>
<item>
Expand Down
2 changes: 1 addition & 1 deletion src/tribler/gui/tests/test_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ def test_tags_dialog(window):
assert widget.content_table.add_tags_dialog.dialog_widget.error_text_label.isVisible()

QTest.keyClick(tags_input, "c")
assert tags_input.tags[-1].text == "aac"
assert tags_input.tags[-1].text == "ac"

# Test creating a new tag by clicking to the right of the right-most tag
QTest.mouseClick(tags_input, Qt.LeftButton, pos=tags_input.tags[-1].rect.topRight().toPoint() + QPoint(10, 0))
Expand Down