Skip to content

Commit

Permalink
Add source and tracker fields
Browse files Browse the repository at this point in the history
  • Loading branch information
drew2a committed Oct 9, 2023
1 parent f03cfba commit b6d21a8
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 91 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import logging
from datetime import datetime
from typing import Optional

from pony import orm

from tribler.core.components.database.db.layers.knowledge_data_access_layer import KnowledgeDataAccessLayer
from tribler.core.components.torrent_checker.torrent_checker.dataclasses import HealthInfo
from tribler.core.upgrade.tags_to_knowledge.previous_dbs.knowledge_db import ResourceType
from tribler.core.utilities.pony_utils import get_or_create


# pylint: disable=redefined-outer-name


class HealthDataAccessLayer:
def __init__(self, knowledge_layer: KnowledgeDataAccessLayer):
self.logger = logging.getLogger(self.__class__.__name__)
self.instance = knowledge_layer.instance
self.Resource = knowledge_layer.Resource
self.TorrentHealth, self.Tracker, self.get_torrent_health = self.define_binding(self.instance)

@staticmethod
def define_binding(db):
class TorrentHealth(db.Entity):
id = orm.PrimaryKey(int, auto=True)

torrent = orm.Required(lambda: db.Resource, index=True)

seeders = orm.Required(int, default=0)
leechers = orm.Required(int, default=0)
source = orm.Required(int, default=0) # Source enum
tracker = orm.Optional(lambda: Tracker)
last_check = orm.Required(datetime, default=datetime.utcnow)

class Tracker(db.Entity):
id = orm.PrimaryKey(int, auto=True)

url = orm.Required(str, unique=True)
last_check = orm.Optional(datetime)
alive = orm.Required(bool, default=True)
failures = orm.Required(int, default=0)

torrents = orm.Set(lambda: db.Resource)
torrent_health_set = orm.Set(lambda: TorrentHealth, reverse='tracker')

def get_torrent_health(infohash: str) -> Optional[TorrentHealth]:
if torrent := db.Resource.get(name=infohash, type=ResourceType.TORRENT):
return TorrentHealth.get(torrent=torrent)
return None

return TorrentHealth, Tracker, get_torrent_health

def add_torrent_health(self, health_info: HealthInfo):
torrent = get_or_create(
self.Resource,
name=health_info.infohash_hex,
type=ResourceType.TORRENT
)

torrent_health = get_or_create(
self.TorrentHealth,
torrent=torrent
)

torrent_health.seeders = health_info.seeders
torrent_health.leechers = health_info.leechers
if health_info.tracker:
torrent_health.tracker = get_or_create(
self.Tracker,
url=health_info.tracker
)

torrent_health.source = health_info.source
torrent_health.last_check = datetime.utcfromtimestamp(health_info.last_check)

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ class Resource(db.Entity):

subject_statements = orm.Set(lambda: Statement, reverse="subject")
object_statements = orm.Set(lambda: Statement, reverse="object")
health_info = orm.Set(lambda: db.HealthInfo, reverse="torrent")
torrent_healths = orm.Set(lambda: db.TorrentHealth, reverse="torrent")
trackers = orm.Set(lambda: db.Tracker, reverse="torrents")

orm.composite_key(name, type)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import os
import time
from datetime import datetime

from tribler.core.components.database.db.layers.knowledge_data_access_layer import ResourceType
from tribler.core.components.database.db.tests.test_tribler_database import TestTriblerDatabase
from tribler.core.components.torrent_checker.torrent_checker.dataclasses import HealthInfo, Source
from tribler.core.utilities.pony_utils import db_session


# pylint: disable=protected-access
class TestHealthAccessLayer(TestTriblerDatabase):

@staticmethod
def create_health_info(tracker=''):
return HealthInfo(
infohash=os.urandom(40),
seeders=10,
leechers=20,
last_check=int(time.time()),
self_checked=True,
source=Source.TRACKER,
tracker=tracker
)

@db_session
def test_add_torrent_health_no_tracker(self):
""" Test that add_torrent_health works as expected"""
info = self.create_health_info()
self.db.health.add_torrent_health(info)

health = self.db.health.get_torrent_health(info.infohash_hex)

assert health.torrent.name == info.infohash_hex
assert health.torrent.type == ResourceType.TORRENT
assert health.seeders == info.seeders
assert health.leechers == info.leechers
assert health.last_check == datetime.utcfromtimestamp(info.last_check)
assert health.source == info.source

assert not health.tracker

assert not self.db.health.get_torrent_health('missed hash')

@db_session
def test_add_torrent_health_with_trackers(self):
""" Test that add_torrent_health considers trackers"""

# first add single HealthInfo with tracker
info = self.create_health_info(tracker='tracker1')
self.db.health.add_torrent_health(info)
health = self.db.health.get_torrent_health(info.infohash_hex)

assert health.tracker.url == info.tracker

# then add another HealthInfo with the same tracker
self.db.health.add_torrent_health(
self.create_health_info(tracker='tracker1')
)

assert len(self.db.Tracker.select()) == 1
assert len(self.db.TorrentHealth.select()) == 2

# then add another HealthInfo with the different tracker
self.db.health.add_torrent_health(
self.create_health_info(tracker='tracker2')
)

assert len(self.db.Tracker.select()) == 2
assert len(self.db.TorrentHealth.select()) == 3

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ def dump_db(self):
self.db.instance.StatementOp.select().show()
print('\nMisc')
self.db.instance.Misc.select().show()
print('\nHealthInfo')
self.db.instance.HealthInfo.select().show()
print('\nTorrentHealth')
self.db.instance.TorrentHealth.select().show()
print('\nTracker')
self.db.instance.Tracker.select().show()

@db_session
def test_set_misc(self):
Expand Down
5 changes: 3 additions & 2 deletions src/tribler/core/components/database/db/tribler_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from pony import orm

from tribler.core.components.database.db.layers.health_data_access_level import HealthDataAccessLayer
from tribler.core.components.database.db.layers.health_data_access_layer import HealthDataAccessLayer
from tribler.core.components.database.db.layers.knowledge_data_access_layer import KnowledgeDataAccessLayer
from tribler.core.utilities.pony_utils import TrackedDatabase, get_or_create

Expand All @@ -22,7 +22,8 @@ def __init__(self, filename: Optional[str] = None, *, create_tables: bool = True
self.Resource = self.knowledge.Resource
self.StatementOp = self.knowledge.StatementOp

self.HealthInfo = self.health.HealthInfo
self.TorrentHealth = self.health.TorrentHealth
self.Tracker = self.health.Tracker

self.instance.bind('sqlite', filename or ':memory:', create_db=True)
generate_mapping_kwargs['create_tables'] = create_tables
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
class Source(IntEnum):
""" Source of the Torrent Health information.
"""
NONE = 0
TRACKER = 1
DHT = 2
UNKNOWN = 0
DHT = 1
TRACKER = 2
POPULARITY_COMMUNITY = 3


Expand All @@ -32,7 +32,8 @@ class HealthInfo:
leechers: int = 0
last_check: int = field(default_factory=lambda: int(time.time()))
self_checked: bool = False
source: Source = Source.NONE
source: Source = Source.UNKNOWN
tracker: str = ''

def __repr__(self):
infohash_repr = hexlify(self.infohash[:4])
Expand Down

0 comments on commit b6d21a8

Please sign in to comment.