torrt 1.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
torrt/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+
2
+ VERSION = '1.1.0'
3
+ """Application version string."""
torrt/base_bot.py ADDED
@@ -0,0 +1,31 @@
1
+ from .exceptions import TorrtBotException
2
+ from .utils import BotClassesRegistry, BotObjectsRegistry, WithSettings
3
+
4
+
5
+ class BaseBot(WithSettings):
6
+
7
+ config_entry_name: str = 'bots'
8
+
9
+ def __init_subclass__(cls, **kwargs):
10
+ if cls.alias:
11
+ BotClassesRegistry.add(cls)
12
+
13
+ def register(self):
14
+ """Adds this object intoBotObjectsRegistry."""
15
+
16
+ BotObjectsRegistry.add(self)
17
+
18
+ def test_configuration(self) -> bool:
19
+ """This should implement a configuration test, for example check given credentials."""
20
+ return False
21
+
22
+ def run(self):
23
+ """Run bot to receive incoming commands."""
24
+
25
+ class BotRegistrationFailed(TorrtBotException):
26
+
27
+ """Bot is failed to register (missing dependency or precondition)
28
+
29
+ This exception must be raised during bot class construction
30
+
31
+ """
torrt/base_notifier.py ADDED
@@ -0,0 +1,46 @@
1
+ from .utils import NotifierClassesRegistry, NotifierObjectsRegistry, WithSettings
2
+
3
+
4
+ class BaseNotifier(WithSettings):
5
+ """Base Notifier class. All Notifier classes should inherit from this."""
6
+
7
+ config_entry_name: str = 'notifiers'
8
+
9
+ def __init_subclass__(cls, **kwargs):
10
+ if cls.alias:
11
+ NotifierClassesRegistry.add(cls)
12
+
13
+ def register(self):
14
+ """Adds this object into NotificationObjectsRegistry."""
15
+
16
+ NotifierObjectsRegistry.add(self)
17
+
18
+ def send_message(self, msg: str): # pragma: nocover
19
+ """Send prepared message
20
+
21
+ :param msg: Prepared by notifier backend message
22
+
23
+ """
24
+ raise NotImplementedError
25
+
26
+ def make_message(self, torrent_data: dict) -> str: # pragma: nocover
27
+ """Creates message in format suitable for notifier backend
28
+
29
+ :param: torrent_data: dictionary with updated torrents data during the walk operation
30
+
31
+ """
32
+ raise NotImplementedError
33
+
34
+ def test_configuration(self) -> bool:
35
+ """This should implement a configuration test, for example check given credentials."""
36
+
37
+ return False
38
+
39
+ def send(self, updated_data):
40
+ """Send message to user
41
+
42
+ :param: updated_data: dict - dictionary with updated torrents data during the walk operation
43
+
44
+ """
45
+ msg = self.make_message(updated_data)
46
+ self.send_message(msg)
torrt/base_rpc.py ADDED
@@ -0,0 +1,83 @@
1
+ from typing import Any, ClassVar
2
+
3
+ from .utils import HttpClient, RPCClassesRegistry, RPCObjectsRegistry, TorrentData, WithSettings
4
+
5
+
6
+ class BaseRPC(WithSettings):
7
+ """Base RPC class. All RPC classes should inherit from this."""
8
+
9
+ config_entry_name: str = 'rpc'
10
+
11
+ torrent_fields_map: ClassVar[dict[str, str]] = {}
12
+ """mapping from torrent fields names in terms of RPC to field names in term of torrt"""
13
+
14
+ enabled: bool = False
15
+
16
+ def __init__(self, **kwargs):
17
+ super().__init__(**kwargs)
18
+
19
+ self.client = HttpClient(
20
+ silence_exceptions=True,
21
+ dump_fname_tpl=f'%(ts)s_{self.__class__.__name__}.json',
22
+ tunnel=False,
23
+ json=True,
24
+ )
25
+ self.logged_in = False
26
+
27
+ def __init_subclass__(cls, **kwargs):
28
+ if cls.alias:
29
+ RPCClassesRegistry.add(cls)
30
+
31
+ def register(self):
32
+ """Adds this object into RPCObjectsRegistry."""
33
+
34
+ RPCObjectsRegistry.add(self)
35
+
36
+ @classmethod
37
+ def normalize_field_names(cls, torrent_info: dict):
38
+ """Translates from torrent fields names in terms of RPC to field names in term of torrt.
39
+ Updates accordingly a given torrent_info inplace.
40
+
41
+ :param torrent_info:
42
+
43
+ """
44
+ for old_name, new_name in cls.torrent_fields_map.items():
45
+ if old_name in torrent_info:
46
+ torrent_info[new_name] = torrent_info[old_name]
47
+
48
+ def method_get_torrents(self, hashes: list[str] | None = None) -> list[dict]: # pragma: nocover
49
+ """This should return a dictionary with torrents info from RPC.
50
+ Each torrent info should be normalized (see normalize_field_names()).
51
+
52
+ :param hashes: torrent hashes
53
+
54
+ """
55
+ raise NotImplementedError
56
+
57
+ def method_add_torrent(
58
+ self, torrent: TorrentData, *, download_to: str = '', params: dict | None = None) -> Any: # pragma: nocover
59
+ """Adds torrent to torrent client using RPC.
60
+
61
+ :param torrent: torrent info
62
+ :param download_to: path to download files from torrent into (in terms of torrent client filesystem)
63
+ :param params: optional information attached to torrent that should be preserved
64
+
65
+ """
66
+ raise NotImplementedError
67
+
68
+ def method_remove_torrent(self, hash_str: str, *, with_data: bool = False) -> Any: # pragma: nocover
69
+ """Removes torrent from torrent client using RPC.
70
+
71
+ :param hash_str: torrent identifying hash
72
+ :param with_data: flag to also remove files from torrent
73
+
74
+ """
75
+ raise NotImplementedError
76
+
77
+ def method_get_version(self) -> str: # pragma: nocover
78
+ """Returns torrent client API version."""
79
+ raise NotImplementedError
80
+
81
+ def test_configuration(self) -> str:
82
+ # This is to conform to common interface.
83
+ return self.method_get_version()