Revert "[Core] Document all exported core methods with type hints"
Typing is broken with older versions of Twisted e.g. with v21.2
deluge/deluge/core/core.py", line 404, in Core
) -> defer.Deferred[str]:
TypeError: 'type' object is not subscriptable
Also it might not be compatible with Python 3.6 or 3.7 with use of
certain types such as dict rather than Dict
This reverts commit 4096cdfdfe
.
Ref: https://twistedmatrix.com/trac/ticket/9816
This commit is contained in:
parent
4096cdfdfe
commit
1089adb844
|
@ -14,7 +14,6 @@ import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
import threading
|
import threading
|
||||||
from base64 import b64decode, b64encode
|
from base64 import b64decode, b64encode
|
||||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
||||||
from urllib.request import URLError, urlopen
|
from urllib.request import URLError, urlopen
|
||||||
|
|
||||||
from twisted.internet import defer, reactor, task
|
from twisted.internet import defer, reactor, task
|
||||||
|
@ -241,12 +240,13 @@ class Core(component.Component):
|
||||||
"""Apply libtorrent session settings.
|
"""Apply libtorrent session settings.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
settings: A dict of lt session settings to apply.
|
settings (dict): A dict of lt session settings to apply.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.session.apply_settings(settings)
|
self.session.apply_settings(settings)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _create_peer_id(version: str) -> str:
|
def _create_peer_id(version):
|
||||||
"""Create a peer_id fingerprint.
|
"""Create a peer_id fingerprint.
|
||||||
|
|
||||||
This creates the peer_id and modifies the release char to identify
|
This creates the peer_id and modifies the release char to identify
|
||||||
|
@ -261,10 +261,11 @@ class Core(component.Component):
|
||||||
``--DE201b--`` (beta pre-release of v2.0.1)
|
``--DE201b--`` (beta pre-release of v2.0.1)
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
version: The version string in PEP440 dotted notation.
|
version (str): The version string in PEP440 dotted notation.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The formatted peer_id with Deluge prefix e.g. '--DE200s--'
|
str: The formatted peer_id with Deluge prefix e.g. '--DE200s--'
|
||||||
|
|
||||||
"""
|
"""
|
||||||
split = deluge.common.VersionSplit(version)
|
split = deluge.common.VersionSplit(version)
|
||||||
# Fill list with zeros to length of 4 and use lt to create fingerprint.
|
# Fill list with zeros to length of 4 and use lt to create fingerprint.
|
||||||
|
@ -313,11 +314,12 @@ class Core(component.Component):
|
||||||
log.info('Restoring backup of %s from: %s', filename, filepath_bak)
|
log.info('Restoring backup of %s from: %s', filename, filepath_bak)
|
||||||
shutil.move(filepath_bak, filepath)
|
shutil.move(filepath_bak, filepath)
|
||||||
|
|
||||||
def _load_session_state(self) -> dict:
|
def _load_session_state(self):
|
||||||
"""Loads the libtorrent session state
|
"""Loads the libtorrent session state
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A libtorrent sesion state, empty dict if unable to load it.
|
dict: A libtorrent sesion state, empty dict if unable to load it.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
filename = 'session.state'
|
filename = 'session.state'
|
||||||
filepath = get_config_dir(filename)
|
filepath = get_config_dir(filename)
|
||||||
|
@ -399,19 +401,18 @@ class Core(component.Component):
|
||||||
|
|
||||||
# Exported Methods
|
# Exported Methods
|
||||||
@export
|
@export
|
||||||
def add_torrent_file_async(
|
def add_torrent_file_async(self, filename, filedump, options, save_state=True):
|
||||||
self, filename: str, filedump: str, options: dict, save_state: bool = True
|
|
||||||
) -> defer.Deferred[Optional[str]]:
|
|
||||||
"""Adds a torrent file to the session asynchronously.
|
"""Adds a torrent file to the session asynchronously.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
filename: The filename of the torrent.
|
filename (str): The filename of the torrent.
|
||||||
filedump: A base64 encoded string of torrent file contents.
|
filedump (str): A base64 encoded string of torrent file contents.
|
||||||
options: The options to apply to the torrent upon adding.
|
options (dict): The options to apply to the torrent upon adding.
|
||||||
save_state: If the state should be saved after adding the file.
|
save_state (bool): If the state should be saved after adding the file.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The torrent ID or None.
|
Deferred: The torrent ID or None.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
filedump = b64decode(filedump)
|
filedump = b64decode(filedump)
|
||||||
|
@ -432,9 +433,7 @@ class Core(component.Component):
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def prefetch_magnet_metadata(
|
def prefetch_magnet_metadata(self, magnet, timeout=30):
|
||||||
self, magnet: str, timeout: int = 30
|
|
||||||
) -> defer.Deferred[Tuple[str, bytes]]:
|
|
||||||
"""Download magnet metadata without adding to Deluge session.
|
"""Download magnet metadata without adding to Deluge session.
|
||||||
|
|
||||||
Used by UIs to get magnet files for selection before adding to session.
|
Used by UIs to get magnet files for selection before adding to session.
|
||||||
|
@ -442,11 +441,12 @@ class Core(component.Component):
|
||||||
The metadata is bencoded and for transfer base64 encoded.
|
The metadata is bencoded and for transfer base64 encoded.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
magnet: The magnet URI.
|
magnet (str): The magnet URI.
|
||||||
timeout: Number of seconds to wait before canceling request.
|
timeout (int): Number of seconds to wait before canceling request.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A tuple of (torrent_id (str), metadata (str)) for the magnet.
|
Deferred: A tuple of (torrent_id (str), metadata (str)) for the magnet.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def on_metadata(result, result_d):
|
def on_metadata(result, result_d):
|
||||||
|
@ -461,18 +461,16 @@ class Core(component.Component):
|
||||||
return result_d
|
return result_d
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def add_torrent_file(
|
def add_torrent_file(self, filename, filedump, options):
|
||||||
self, filename: str, filedump: Union[str, bytes], options: dict
|
|
||||||
) -> Optional[str]:
|
|
||||||
"""Adds a torrent file to the session.
|
"""Adds a torrent file to the session.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
filename: The filename of the torrent.
|
filename (str): The filename of the torrent.
|
||||||
filedump: A base64 encoded string of the torrent file contents.
|
filedump (str): A base64 encoded string of the torrent file contents.
|
||||||
options: The options to apply to the torrent upon adding.
|
options (dict): The options to apply to the torrent upon adding.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The torrent_id or None.
|
str: The torrent_id or None.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
filedump = b64decode(filedump)
|
filedump = b64decode(filedump)
|
||||||
|
@ -488,17 +486,16 @@ class Core(component.Component):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def add_torrent_files(
|
def add_torrent_files(self, torrent_files):
|
||||||
self, torrent_files: List[Tuple[str, Union[str, bytes], dict]]
|
|
||||||
) -> defer.Deferred[List[AddTorrentError]]:
|
|
||||||
"""Adds multiple torrent files to the session asynchronously.
|
"""Adds multiple torrent files to the session asynchronously.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
torrent_files: Torrent files as tuple of
|
torrent_files (list of tuples): Torrent files as tuple of
|
||||||
``(filename, filedump, options)``.
|
``(filename, filedump, options)``.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A list of errors (if there were any)
|
Deferred
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
|
@ -518,19 +515,19 @@ class Core(component.Component):
|
||||||
return task.deferLater(reactor, 0, add_torrents)
|
return task.deferLater(reactor, 0, add_torrents)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def add_torrent_url(
|
def add_torrent_url(self, url, options, headers=None):
|
||||||
self, url: str, options: dict, headers: dict = None
|
"""
|
||||||
) -> defer.Deferred[Optional[str]]:
|
Adds a torrent from a URL. Deluge will attempt to fetch the torrent
|
||||||
"""Adds a torrent from a URL. Deluge will attempt to fetch the torrent
|
|
||||||
from the URL prior to adding it to the session.
|
from the URL prior to adding it to the session.
|
||||||
|
|
||||||
Args:
|
:param url: the URL pointing to the torrent file
|
||||||
url: the URL pointing to the torrent file
|
:type url: string
|
||||||
options: the options to apply to the torrent on add
|
:param options: the options to apply to the torrent on add
|
||||||
headers: any optional headers to send
|
:type options: dict
|
||||||
|
:param headers: any optional headers to send
|
||||||
|
:type headers: dict
|
||||||
|
|
||||||
Returns:
|
:returns: a Deferred which returns the torrent_id as a str or None
|
||||||
a Deferred which returns the torrent_id as a str or None
|
|
||||||
"""
|
"""
|
||||||
log.info('Attempting to add URL %s', url)
|
log.info('Attempting to add URL %s', url)
|
||||||
|
|
||||||
|
@ -556,52 +553,55 @@ class Core(component.Component):
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def add_torrent_magnet(self, uri: str, options: dict) -> str:
|
def add_torrent_magnet(self, uri, options):
|
||||||
"""Adds a torrent from a magnet link.
|
"""
|
||||||
|
Adds a torrent from a magnet link.
|
||||||
|
|
||||||
Args:
|
:param uri: the magnet link
|
||||||
uri: the magnet link
|
:type uri: string
|
||||||
options: the options to apply to the torrent on add
|
:param options: the options to apply to the torrent on add
|
||||||
|
:type options: dict
|
||||||
|
|
||||||
|
:returns: the torrent_id
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
Returns:
|
|
||||||
the torrent_id
|
|
||||||
"""
|
"""
|
||||||
log.debug('Attempting to add by magnet URI: %s', uri)
|
log.debug('Attempting to add by magnet URI: %s', uri)
|
||||||
|
|
||||||
return self.torrentmanager.add(magnet=uri, options=options)
|
return self.torrentmanager.add(magnet=uri, options=options)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def remove_torrent(self, torrent_id: str, remove_data: bool) -> bool:
|
def remove_torrent(self, torrent_id, remove_data):
|
||||||
"""Removes a single torrent from the session.
|
"""Removes a single torrent from the session.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
torrent_id: The torrent ID to remove.
|
torrent_id (str): The torrent ID to remove.
|
||||||
remove_data: If True, also remove the downloaded data.
|
remove_data (bool): If True, also remove the downloaded data.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if removed successfully.
|
bool: True if removed successfully.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
InvalidTorrentError: If the torrent ID does not exist in the session.
|
InvalidTorrentError: If the torrent ID does not exist in the session.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
log.debug('Removing torrent %s from the core.', torrent_id)
|
log.debug('Removing torrent %s from the core.', torrent_id)
|
||||||
return self.torrentmanager.remove(torrent_id, remove_data)
|
return self.torrentmanager.remove(torrent_id, remove_data)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def remove_torrents(
|
def remove_torrents(self, torrent_ids, remove_data):
|
||||||
self, torrent_ids: List[str], remove_data: bool
|
|
||||||
) -> defer.Deferred[List[Tuple[str, str]]]:
|
|
||||||
"""Remove multiple torrents from the session.
|
"""Remove multiple torrents from the session.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
torrent_ids: The torrent IDs to remove.
|
torrent_ids (list): The torrent IDs to remove.
|
||||||
remove_data: If True, also remove the downloaded data.
|
remove_data (bool): If True, also remove the downloaded data.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
An empty list if no errors occurred otherwise the list contains
|
list: An empty list if no errors occurred otherwise the list contains
|
||||||
tuples of strings, a torrent ID and an error message. For example:
|
tuples of strings, a torrent ID and an error message. For example:
|
||||||
|
|
||||||
|
[('<torrent_id>', 'Error removing torrent')]
|
||||||
|
|
||||||
[('<torrent_id>', 'Error removing torrent')]
|
|
||||||
"""
|
"""
|
||||||
log.info('Removing %d torrents from core.', len(torrent_ids))
|
log.info('Removing %d torrents from core.', len(torrent_ids))
|
||||||
|
|
||||||
|
@ -625,17 +625,17 @@ class Core(component.Component):
|
||||||
return task.deferLater(reactor, 0, do_remove_torrents)
|
return task.deferLater(reactor, 0, do_remove_torrents)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_session_status(self, keys: List[str]) -> Dict[str, Union[int, float]]:
|
def get_session_status(self, keys):
|
||||||
"""Gets the session status values for 'keys', these keys are taking
|
"""Gets the session status values for 'keys', these keys are taking
|
||||||
from libtorrent's session status.
|
from libtorrent's session status.
|
||||||
|
|
||||||
See: http://www.rasterbar.com/products/libtorrent/manual.html#status
|
See: http://www.rasterbar.com/products/libtorrent/manual.html#status
|
||||||
|
|
||||||
Args:
|
:param keys: the keys for which we want values
|
||||||
keys: the keys for which we want values
|
:type keys: list
|
||||||
|
:returns: a dictionary of {key: value, ...}
|
||||||
|
:rtype: dict
|
||||||
|
|
||||||
Returns:
|
|
||||||
a dictionary of {key: value, ...}
|
|
||||||
"""
|
"""
|
||||||
if not keys:
|
if not keys:
|
||||||
return self.session_status
|
return self.session_status
|
||||||
|
@ -656,13 +656,13 @@ class Core(component.Component):
|
||||||
return status
|
return status
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def force_reannounce(self, torrent_ids: List[str]) -> None:
|
def force_reannounce(self, torrent_ids):
|
||||||
log.debug('Forcing reannouncment to: %s', torrent_ids)
|
log.debug('Forcing reannouncment to: %s', torrent_ids)
|
||||||
for torrent_id in torrent_ids:
|
for torrent_id in torrent_ids:
|
||||||
self.torrentmanager[torrent_id].force_reannounce()
|
self.torrentmanager[torrent_id].force_reannounce()
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def pause_torrent(self, torrent_id: str) -> None:
|
def pause_torrent(self, torrent_id):
|
||||||
"""Pauses a torrent"""
|
"""Pauses a torrent"""
|
||||||
log.debug('Pausing: %s', torrent_id)
|
log.debug('Pausing: %s', torrent_id)
|
||||||
if not isinstance(torrent_id, str):
|
if not isinstance(torrent_id, str):
|
||||||
|
@ -671,7 +671,7 @@ class Core(component.Component):
|
||||||
self.torrentmanager[torrent_id].pause()
|
self.torrentmanager[torrent_id].pause()
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def pause_torrents(self, torrent_ids: List[str] = None) -> None:
|
def pause_torrents(self, torrent_ids=None):
|
||||||
"""Pauses a list of torrents"""
|
"""Pauses a list of torrents"""
|
||||||
if not torrent_ids:
|
if not torrent_ids:
|
||||||
torrent_ids = self.torrentmanager.get_torrent_list()
|
torrent_ids = self.torrentmanager.get_torrent_list()
|
||||||
|
@ -679,27 +679,27 @@ class Core(component.Component):
|
||||||
self.pause_torrent(torrent_id)
|
self.pause_torrent(torrent_id)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def connect_peer(self, torrent_id: str, ip: str, port: int):
|
def connect_peer(self, torrent_id, ip, port):
|
||||||
log.debug('adding peer %s to %s', ip, torrent_id)
|
log.debug('adding peer %s to %s', ip, torrent_id)
|
||||||
if not self.torrentmanager[torrent_id].connect_peer(ip, port):
|
if not self.torrentmanager[torrent_id].connect_peer(ip, port):
|
||||||
log.warning('Error adding peer %s:%s to %s', ip, port, torrent_id)
|
log.warning('Error adding peer %s:%s to %s', ip, port, torrent_id)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def move_storage(self, torrent_ids: List[str], dest: str):
|
def move_storage(self, torrent_ids, dest):
|
||||||
log.debug('Moving storage %s to %s', torrent_ids, dest)
|
log.debug('Moving storage %s to %s', torrent_ids, dest)
|
||||||
for torrent_id in torrent_ids:
|
for torrent_id in torrent_ids:
|
||||||
if not self.torrentmanager[torrent_id].move_storage(dest):
|
if not self.torrentmanager[torrent_id].move_storage(dest):
|
||||||
log.warning('Error moving torrent %s to %s', torrent_id, dest)
|
log.warning('Error moving torrent %s to %s', torrent_id, dest)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def pause_session(self) -> None:
|
def pause_session(self):
|
||||||
"""Pause the entire session"""
|
"""Pause the entire session"""
|
||||||
if not self.session.is_paused():
|
if not self.session.is_paused():
|
||||||
self.session.pause()
|
self.session.pause()
|
||||||
component.get('EventManager').emit(SessionPausedEvent())
|
component.get('EventManager').emit(SessionPausedEvent())
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def resume_session(self) -> None:
|
def resume_session(self):
|
||||||
"""Resume the entire session"""
|
"""Resume the entire session"""
|
||||||
if self.session.is_paused():
|
if self.session.is_paused():
|
||||||
self.session.resume()
|
self.session.resume()
|
||||||
|
@ -708,12 +708,12 @@ class Core(component.Component):
|
||||||
component.get('EventManager').emit(SessionResumedEvent())
|
component.get('EventManager').emit(SessionResumedEvent())
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def is_session_paused(self) -> bool:
|
def is_session_paused(self):
|
||||||
"""Returns the activity of the session"""
|
"""Returns the activity of the session"""
|
||||||
return self.session.is_paused()
|
return self.session.is_paused()
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def resume_torrent(self, torrent_id: str) -> None:
|
def resume_torrent(self, torrent_id):
|
||||||
"""Resumes a torrent"""
|
"""Resumes a torrent"""
|
||||||
log.debug('Resuming: %s', torrent_id)
|
log.debug('Resuming: %s', torrent_id)
|
||||||
if not isinstance(torrent_id, str):
|
if not isinstance(torrent_id, str):
|
||||||
|
@ -722,7 +722,7 @@ class Core(component.Component):
|
||||||
self.torrentmanager[torrent_id].resume()
|
self.torrentmanager[torrent_id].resume()
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def resume_torrents(self, torrent_ids: List[str] = None) -> None:
|
def resume_torrents(self, torrent_ids=None):
|
||||||
"""Resumes a list of torrents"""
|
"""Resumes a list of torrents"""
|
||||||
if not torrent_ids:
|
if not torrent_ids:
|
||||||
torrent_ids = self.torrentmanager.get_torrent_list()
|
torrent_ids = self.torrentmanager.get_torrent_list()
|
||||||
|
@ -755,9 +755,7 @@ class Core(component.Component):
|
||||||
return status
|
return status
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_torrent_status(
|
def get_torrent_status(self, torrent_id, keys, diff=False):
|
||||||
self, torrent_id: str, keys: List[str], diff: bool = False
|
|
||||||
) -> dict:
|
|
||||||
torrent_keys, plugin_keys = self.torrentmanager.separate_keys(
|
torrent_keys, plugin_keys = self.torrentmanager.separate_keys(
|
||||||
keys, [torrent_id]
|
keys, [torrent_id]
|
||||||
)
|
)
|
||||||
|
@ -772,10 +770,10 @@ class Core(component.Component):
|
||||||
|
|
||||||
@export
|
@export
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_torrents_status(
|
def get_torrents_status(self, filter_dict, keys, diff=False):
|
||||||
self, filter_dict: dict, keys: List[str], diff: bool = False
|
"""
|
||||||
) -> dict:
|
returns all torrents , optionally filtered by filter_dict.
|
||||||
"""returns all torrents , optionally filtered by filter_dict."""
|
"""
|
||||||
all_keys = not keys
|
all_keys = not keys
|
||||||
torrent_ids = self.filtermanager.filter_torrent_ids(filter_dict)
|
torrent_ids = self.filtermanager.filter_torrent_ids(filter_dict)
|
||||||
status_dict, plugin_keys = yield self.torrentmanager.torrents_status_update(
|
status_dict, plugin_keys = yield self.torrentmanager.torrents_status_update(
|
||||||
|
@ -788,37 +786,36 @@ class Core(component.Component):
|
||||||
return status_dict
|
return status_dict
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_filter_tree(
|
def get_filter_tree(self, show_zero_hits=True, hide_cat=None):
|
||||||
self, show_zero_hits: bool = True, hide_cat: List[str] = None
|
"""
|
||||||
) -> Dict:
|
returns {field: [(value,count)] }
|
||||||
"""returns {field: [(value,count)] }
|
|
||||||
for use in sidebar(s)
|
for use in sidebar(s)
|
||||||
"""
|
"""
|
||||||
return self.filtermanager.get_filter_tree(show_zero_hits, hide_cat)
|
return self.filtermanager.get_filter_tree(show_zero_hits, hide_cat)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_session_state(self) -> List[str]:
|
def get_session_state(self):
|
||||||
"""Returns a list of torrent_ids in the session."""
|
"""Returns a list of torrent_ids in the session."""
|
||||||
# Get the torrent list from the TorrentManager
|
# Get the torrent list from the TorrentManager
|
||||||
return self.torrentmanager.get_torrent_list()
|
return self.torrentmanager.get_torrent_list()
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_config(self) -> dict:
|
def get_config(self):
|
||||||
"""Get all the preferences as a dictionary"""
|
"""Get all the preferences as a dictionary"""
|
||||||
return self.config.config
|
return self.config.config
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_config_value(self, key: str) -> Any:
|
def get_config_value(self, key):
|
||||||
"""Get the config value for key"""
|
"""Get the config value for key"""
|
||||||
return self.config.get(key)
|
return self.config.get(key)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_config_values(self, keys: List[str]) -> Dict[str, Any]:
|
def get_config_values(self, keys):
|
||||||
"""Get the config values for the entered keys"""
|
"""Get the config values for the entered keys"""
|
||||||
return {key: self.config.get(key) for key in keys}
|
return {key: self.config.get(key) for key in keys}
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def set_config(self, config: Dict[str, Any]):
|
def set_config(self, config):
|
||||||
"""Set the config with values from dictionary"""
|
"""Set the config with values from dictionary"""
|
||||||
# Load all the values into the configuration
|
# Load all the values into the configuration
|
||||||
for key in config:
|
for key in config:
|
||||||
|
@ -827,20 +824,21 @@ class Core(component.Component):
|
||||||
self.config[key] = config[key]
|
self.config[key] = config[key]
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_listen_port(self) -> int:
|
def get_listen_port(self):
|
||||||
"""Returns the active listen port"""
|
"""Returns the active listen port"""
|
||||||
return self.session.listen_port()
|
return self.session.listen_port()
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_proxy(self) -> Dict[str, Any]:
|
def get_proxy(self):
|
||||||
"""Returns the proxy settings
|
"""Returns the proxy settings
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Proxy settings.
|
dict: Contains proxy settings.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
Proxy type names:
|
Proxy type names:
|
||||||
0: None, 1: Socks4, 2: Socks5, 3: Socks5 w Auth, 4: HTTP, 5: HTTP w Auth, 6: I2P
|
0: None, 1: Socks4, 2: Socks5, 3: Socks5 w Auth, 4: HTTP, 5: HTTP w Auth, 6: I2P
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
settings = self.session.get_settings()
|
settings = self.session.get_settings()
|
||||||
|
@ -863,38 +861,36 @@ class Core(component.Component):
|
||||||
return proxy_dict
|
return proxy_dict
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_available_plugins(self) -> List[str]:
|
def get_available_plugins(self):
|
||||||
"""Returns a list of plugins available in the core"""
|
"""Returns a list of plugins available in the core"""
|
||||||
return self.pluginmanager.get_available_plugins()
|
return self.pluginmanager.get_available_plugins()
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_enabled_plugins(self) -> List[str]:
|
def get_enabled_plugins(self):
|
||||||
"""Returns a list of enabled plugins in the core"""
|
"""Returns a list of enabled plugins in the core"""
|
||||||
return self.pluginmanager.get_enabled_plugins()
|
return self.pluginmanager.get_enabled_plugins()
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def enable_plugin(self, plugin: str) -> defer.Deferred[bool]:
|
def enable_plugin(self, plugin):
|
||||||
return self.pluginmanager.enable_plugin(plugin)
|
return self.pluginmanager.enable_plugin(plugin)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def disable_plugin(self, plugin: str) -> defer.Deferred[bool]:
|
def disable_plugin(self, plugin):
|
||||||
return self.pluginmanager.disable_plugin(plugin)
|
return self.pluginmanager.disable_plugin(plugin)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def force_recheck(self, torrent_ids: List[str]) -> None:
|
def force_recheck(self, torrent_ids):
|
||||||
"""Forces a data recheck on torrent_ids"""
|
"""Forces a data recheck on torrent_ids"""
|
||||||
for torrent_id in torrent_ids:
|
for torrent_id in torrent_ids:
|
||||||
self.torrentmanager[torrent_id].force_recheck()
|
self.torrentmanager[torrent_id].force_recheck()
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def set_torrent_options(
|
def set_torrent_options(self, torrent_ids, options):
|
||||||
self, torrent_ids: List[str], options: Dict[str, Any]
|
|
||||||
) -> None:
|
|
||||||
"""Sets the torrent options for torrent_ids
|
"""Sets the torrent options for torrent_ids
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
torrent_ids: A list of torrent_ids to set the options for.
|
torrent_ids (list): A list of torrent_ids to set the options for.
|
||||||
options: A dict of torrent options to set. See
|
options (dict): A dict of torrent options to set. See
|
||||||
``torrent.TorrentOptions`` class for valid keys.
|
``torrent.TorrentOptions`` class for valid keys.
|
||||||
"""
|
"""
|
||||||
if 'owner' in options and not self.authmanager.has_account(options['owner']):
|
if 'owner' in options and not self.authmanager.has_account(options['owner']):
|
||||||
|
@ -907,14 +903,12 @@ class Core(component.Component):
|
||||||
self.torrentmanager[torrent_id].set_options(options)
|
self.torrentmanager[torrent_id].set_options(options)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def set_torrent_trackers(
|
def set_torrent_trackers(self, torrent_id, trackers):
|
||||||
self, torrent_id: str, trackers: List[Dict[str, Any]]
|
|
||||||
) -> None:
|
|
||||||
"""Sets a torrents tracker list. trackers will be ``[{"url", "tier"}]``"""
|
"""Sets a torrents tracker list. trackers will be ``[{"url", "tier"}]``"""
|
||||||
return self.torrentmanager[torrent_id].set_trackers(trackers)
|
return self.torrentmanager[torrent_id].set_trackers(trackers)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_magnet_uri(self, torrent_id: str) -> str:
|
def get_magnet_uri(self, torrent_id):
|
||||||
return self.torrentmanager[torrent_id].get_magnet_uri()
|
return self.torrentmanager[torrent_id].get_magnet_uri()
|
||||||
|
|
||||||
@deprecated
|
@deprecated
|
||||||
|
@ -1062,7 +1056,7 @@ class Core(component.Component):
|
||||||
self.add_torrent_file(os.path.split(target)[1], filedump, options)
|
self.add_torrent_file(os.path.split(target)[1], filedump, options)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def upload_plugin(self, filename: str, filedump: Union[str, bytes]) -> None:
|
def upload_plugin(self, filename, filedump):
|
||||||
"""This method is used to upload new plugins to the daemon. It is used
|
"""This method is used to upload new plugins to the daemon. It is used
|
||||||
when connecting to the daemon remotely and installing a new plugin on
|
when connecting to the daemon remotely and installing a new plugin on
|
||||||
the client side. ``plugin_data`` is a ``xmlrpc.Binary`` object of the file data,
|
the client side. ``plugin_data`` is a ``xmlrpc.Binary`` object of the file data,
|
||||||
|
@ -1080,24 +1074,26 @@ class Core(component.Component):
|
||||||
component.get('CorePluginManager').scan_for_plugins()
|
component.get('CorePluginManager').scan_for_plugins()
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def rescan_plugins(self) -> None:
|
def rescan_plugins(self):
|
||||||
"""Re-scans the plugin folders for new plugins"""
|
"""
|
||||||
|
Re-scans the plugin folders for new plugins
|
||||||
|
"""
|
||||||
component.get('CorePluginManager').scan_for_plugins()
|
component.get('CorePluginManager').scan_for_plugins()
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def rename_files(
|
def rename_files(self, torrent_id, filenames):
|
||||||
self, torrent_id: str, filenames: List[Tuple[int, str]]
|
"""
|
||||||
) -> defer.Deferred:
|
Rename files in ``torrent_id``. Since this is an asynchronous operation by
|
||||||
"""Rename files in ``torrent_id``. Since this is an asynchronous operation by
|
|
||||||
libtorrent, watch for the TorrentFileRenamedEvent to know when the
|
libtorrent, watch for the TorrentFileRenamedEvent to know when the
|
||||||
files have been renamed.
|
files have been renamed.
|
||||||
|
|
||||||
Args:
|
:param torrent_id: the torrent_id to rename files
|
||||||
torrent_id: the torrent_id to rename files
|
:type torrent_id: string
|
||||||
filenames: a list of index, filename pairs
|
:param filenames: a list of index, filename pairs
|
||||||
|
:type filenames: ((index, filename), ...)
|
||||||
|
|
||||||
|
:raises InvalidTorrentError: if torrent_id is invalid
|
||||||
|
|
||||||
Raises:
|
|
||||||
InvalidTorrentError: if torrent_id is invalid
|
|
||||||
"""
|
"""
|
||||||
if torrent_id not in self.torrentmanager.torrents:
|
if torrent_id not in self.torrentmanager.torrents:
|
||||||
raise InvalidTorrentError('torrent_id is not in session')
|
raise InvalidTorrentError('torrent_id is not in session')
|
||||||
|
@ -1108,20 +1104,21 @@ class Core(component.Component):
|
||||||
return task.deferLater(reactor, 0, rename)
|
return task.deferLater(reactor, 0, rename)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def rename_folder(
|
def rename_folder(self, torrent_id, folder, new_folder):
|
||||||
self, torrent_id: str, folder: str, new_folder: str
|
"""
|
||||||
) -> defer.Deferred:
|
Renames the 'folder' to 'new_folder' in 'torrent_id'. Watch for the
|
||||||
"""Renames the 'folder' to 'new_folder' in 'torrent_id'. Watch for the
|
|
||||||
TorrentFolderRenamedEvent which is emitted when the folder has been
|
TorrentFolderRenamedEvent which is emitted when the folder has been
|
||||||
renamed successfully.
|
renamed successfully.
|
||||||
|
|
||||||
Args:
|
:param torrent_id: the torrent to rename folder in
|
||||||
torrent_id: the torrent to rename folder in
|
:type torrent_id: string
|
||||||
folder: the folder to rename
|
:param folder: the folder to rename
|
||||||
new_folder: the new folder name
|
:type folder: string
|
||||||
|
:param new_folder: the new folder name
|
||||||
|
:type new_folder: string
|
||||||
|
|
||||||
|
:raises InvalidTorrentError: if the torrent_id is invalid
|
||||||
|
|
||||||
Raises:
|
|
||||||
InvalidTorrentError: if the torrent_id is invalid
|
|
||||||
"""
|
"""
|
||||||
if torrent_id not in self.torrentmanager.torrents:
|
if torrent_id not in self.torrentmanager.torrents:
|
||||||
raise InvalidTorrentError('torrent_id is not in session')
|
raise InvalidTorrentError('torrent_id is not in session')
|
||||||
|
@ -1129,7 +1126,7 @@ class Core(component.Component):
|
||||||
return self.torrentmanager[torrent_id].rename_folder(folder, new_folder)
|
return self.torrentmanager[torrent_id].rename_folder(folder, new_folder)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def queue_top(self, torrent_ids: List[str]) -> None:
|
def queue_top(self, torrent_ids):
|
||||||
log.debug('Attempting to queue %s to top', torrent_ids)
|
log.debug('Attempting to queue %s to top', torrent_ids)
|
||||||
# torrent_ids must be sorted in reverse before moving to preserve order
|
# torrent_ids must be sorted in reverse before moving to preserve order
|
||||||
for torrent_id in sorted(
|
for torrent_id in sorted(
|
||||||
|
@ -1143,7 +1140,7 @@ class Core(component.Component):
|
||||||
log.warning('torrent_id: %s does not exist in the queue', torrent_id)
|
log.warning('torrent_id: %s does not exist in the queue', torrent_id)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def queue_up(self, torrent_ids: List[str]) -> None:
|
def queue_up(self, torrent_ids):
|
||||||
log.debug('Attempting to queue %s to up', torrent_ids)
|
log.debug('Attempting to queue %s to up', torrent_ids)
|
||||||
torrents = (
|
torrents = (
|
||||||
(self.torrentmanager.get_queue_position(torrent_id), torrent_id)
|
(self.torrentmanager.get_queue_position(torrent_id), torrent_id)
|
||||||
|
@ -1168,7 +1165,7 @@ class Core(component.Component):
|
||||||
prev_queue_position = queue_position
|
prev_queue_position = queue_position
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def queue_down(self, torrent_ids: List[str]) -> None:
|
def queue_down(self, torrent_ids):
|
||||||
log.debug('Attempting to queue %s to down', torrent_ids)
|
log.debug('Attempting to queue %s to down', torrent_ids)
|
||||||
torrents = (
|
torrents = (
|
||||||
(self.torrentmanager.get_queue_position(torrent_id), torrent_id)
|
(self.torrentmanager.get_queue_position(torrent_id), torrent_id)
|
||||||
|
@ -1193,7 +1190,7 @@ class Core(component.Component):
|
||||||
prev_queue_position = queue_position
|
prev_queue_position = queue_position
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def queue_bottom(self, torrent_ids: List[str]) -> None:
|
def queue_bottom(self, torrent_ids):
|
||||||
log.debug('Attempting to queue %s to bottom', torrent_ids)
|
log.debug('Attempting to queue %s to bottom', torrent_ids)
|
||||||
# torrent_ids must be sorted before moving to preserve order
|
# torrent_ids must be sorted before moving to preserve order
|
||||||
for torrent_id in sorted(
|
for torrent_id in sorted(
|
||||||
|
@ -1207,15 +1204,17 @@ class Core(component.Component):
|
||||||
log.warning('torrent_id: %s does not exist in the queue', torrent_id)
|
log.warning('torrent_id: %s does not exist in the queue', torrent_id)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def glob(self, path: str) -> List[str]:
|
def glob(self, path):
|
||||||
return glob.glob(path)
|
return glob.glob(path)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def test_listen_port(self) -> defer.Deferred[Optional[bool]]:
|
def test_listen_port(self):
|
||||||
"""Checks if the active port is open
|
"""
|
||||||
|
Checks if the active port is open
|
||||||
|
|
||||||
|
:returns: True if the port is open, False if not
|
||||||
|
:rtype: bool
|
||||||
|
|
||||||
Returns:
|
|
||||||
True if the port is open, False if not
|
|
||||||
"""
|
"""
|
||||||
port = self.get_listen_port()
|
port = self.get_listen_port()
|
||||||
url = 'https://deluge-torrent.org/test_port.php?port=%s' % port
|
url = 'https://deluge-torrent.org/test_port.php?port=%s' % port
|
||||||
|
@ -1234,17 +1233,18 @@ class Core(component.Component):
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_free_space(self, path: str = None) -> int:
|
def get_free_space(self, path=None):
|
||||||
"""Returns the number of free bytes at path
|
"""
|
||||||
|
Returns the number of free bytes at path
|
||||||
|
|
||||||
Args:
|
:param path: the path to check free space at, if None, use the default download location
|
||||||
path: the path to check free space at, if None, use the default download location
|
:type path: string
|
||||||
|
|
||||||
Returns:
|
:returns: the number of free bytes at path
|
||||||
the number of free bytes at path
|
:rtype: int
|
||||||
|
|
||||||
|
:raises InvalidPathError: if the path is invalid
|
||||||
|
|
||||||
Raises:
|
|
||||||
InvalidPathError: if the path is invalid
|
|
||||||
"""
|
"""
|
||||||
if not path:
|
if not path:
|
||||||
path = self.config['download_location']
|
path = self.config['download_location']
|
||||||
|
@ -1257,40 +1257,46 @@ class Core(component.Component):
|
||||||
self.external_ip = external_ip
|
self.external_ip = external_ip
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_external_ip(self) -> str:
|
def get_external_ip(self):
|
||||||
"""Returns the external IP address received from libtorrent."""
|
"""
|
||||||
|
Returns the external IP address received from libtorrent.
|
||||||
|
"""
|
||||||
return self.external_ip
|
return self.external_ip
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_libtorrent_version(self) -> str:
|
def get_libtorrent_version(self):
|
||||||
"""Returns the libtorrent version.
|
"""
|
||||||
|
Returns the libtorrent version.
|
||||||
|
|
||||||
|
:returns: the version
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
Returns:
|
|
||||||
the version
|
|
||||||
"""
|
"""
|
||||||
return LT_VERSION
|
return LT_VERSION
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def get_completion_paths(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
def get_completion_paths(self, args):
|
||||||
"""Returns the available path completions for the input value."""
|
"""
|
||||||
|
Returns the available path completions for the input value.
|
||||||
|
"""
|
||||||
return path_chooser_common.get_completion_paths(args)
|
return path_chooser_common.get_completion_paths(args)
|
||||||
|
|
||||||
@export(AUTH_LEVEL_ADMIN)
|
@export(AUTH_LEVEL_ADMIN)
|
||||||
def get_known_accounts(self) -> List[Dict[str, Any]]:
|
def get_known_accounts(self):
|
||||||
return self.authmanager.get_known_accounts()
|
return self.authmanager.get_known_accounts()
|
||||||
|
|
||||||
@export(AUTH_LEVEL_NONE)
|
@export(AUTH_LEVEL_NONE)
|
||||||
def get_auth_levels_mappings(self) -> Tuple[Dict[str, int], Dict[int, str]]:
|
def get_auth_levels_mappings(self):
|
||||||
return (AUTH_LEVELS_MAPPING, AUTH_LEVELS_MAPPING_REVERSE)
|
return (AUTH_LEVELS_MAPPING, AUTH_LEVELS_MAPPING_REVERSE)
|
||||||
|
|
||||||
@export(AUTH_LEVEL_ADMIN)
|
@export(AUTH_LEVEL_ADMIN)
|
||||||
def create_account(self, username: str, password: str, authlevel: str) -> bool:
|
def create_account(self, username, password, authlevel):
|
||||||
return self.authmanager.create_account(username, password, authlevel)
|
return self.authmanager.create_account(username, password, authlevel)
|
||||||
|
|
||||||
@export(AUTH_LEVEL_ADMIN)
|
@export(AUTH_LEVEL_ADMIN)
|
||||||
def update_account(self, username: str, password: str, authlevel: str) -> bool:
|
def update_account(self, username, password, authlevel):
|
||||||
return self.authmanager.update_account(username, password, authlevel)
|
return self.authmanager.update_account(username, password, authlevel)
|
||||||
|
|
||||||
@export(AUTH_LEVEL_ADMIN)
|
@export(AUTH_LEVEL_ADMIN)
|
||||||
def remove_account(self, username: str) -> bool:
|
def remove_account(self, username):
|
||||||
return self.authmanager.remove_account(username)
|
return self.authmanager.remove_account(username)
|
||||||
|
|
|
@ -40,7 +40,7 @@ def get_completion_paths(args):
|
||||||
:param args: options
|
:param args: options
|
||||||
:type args: dict
|
:type args: dict
|
||||||
:returns: the args argument containing the available completions for the completion_text
|
:returns: the args argument containing the available completions for the completion_text
|
||||||
:rtype: dict
|
:rtype: list
|
||||||
|
|
||||||
"""
|
"""
|
||||||
args['paths'] = []
|
args['paths'] = []
|
||||||
|
|
|
@ -2,4 +2,3 @@ sphinx==4.*
|
||||||
myst-parser
|
myst-parser
|
||||||
sphinx_rtd_theme
|
sphinx_rtd_theme
|
||||||
sphinxcontrib-spelling==7.3.0
|
sphinxcontrib-spelling==7.3.0
|
||||||
sphinx-autodoc-typehints
|
|
||||||
|
|
|
@ -48,7 +48,6 @@ extensions = [
|
||||||
'sphinx.ext.coverage',
|
'sphinx.ext.coverage',
|
||||||
'sphinxcontrib.spelling',
|
'sphinxcontrib.spelling',
|
||||||
'myst_parser',
|
'myst_parser',
|
||||||
'sphinx_autodoc_typehints',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
napoleon_include_init_with_doc = True
|
napoleon_include_init_with_doc = True
|
||||||
|
|
Loading…
Reference in New Issue