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

feat!: support 4.1.0-beta.1, rpc version 18 #399

Merged
merged 44 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
f76afd2
feat: support rpc version 18
trim21 Apr 8, 2024
52de6e2
fix
trim21 Apr 8, 2024
816cd15
Merge branch 'master' into rpc-version-18
trim21 May 13, 2024
cd8cc02
fix
trim21 May 13, 2024
9b3b4d5
fix doc
trim21 May 13, 2024
beca364
fix
trim21 May 13, 2024
0f632b0
update docs
trim21 May 13, 2024
c1493f7
more
trim21 May 13, 2024
d7bf36d
fix
trim21 May 13, 2024
0b3daa2
add inline doc
trim21 May 13, 2024
95dda4d
add inline doc
trim21 May 13, 2024
3ddccc5
fix doc
trim21 May 13, 2024
d837cfa
fix
trim21 May 13, 2024
3342291
Merge branch 'master' into rpc-version-18
trim21 May 17, 2024
c144273
Update client.rst
trim21 May 17, 2024
b77eab9
Update client.rst
trim21 May 17, 2024
d7d9d06
Merge branch 'master' into rpc-version-18
trim21 May 17, 2024
3dba12d
chore: remove ruff from dev-deps
trim21 May 17, 2024
fcca3a9
chore: add bump to taskfile
trim21 May 17, 2024
415acf7
chore: remove dead isort config
trim21 May 17, 2024
5d8009e
style: enable mypy strict (#423)
trim21 May 18, 2024
406128e
docs: improve code (#424)
trim21 May 18, 2024
3c21d8a
merge
trim21 May 18, 2024
9c005bb
update
trim21 May 18, 2024
509083c
update
trim21 May 18, 2024
6e98cd7
update
trim21 May 18, 2024
f910072
update
trim21 May 18, 2024
7804d14
update
trim21 May 18, 2024
32e4262
update
trim21 May 18, 2024
6d82f1a
update
trim21 May 18, 2024
0d91d90
fix
trim21 May 18, 2024
bc1ee30
update
trim21 May 18, 2024
00e1505
Merge remote-tracking branch 'origin/master' into rpc-version-18
trim21 Jun 6, 2024
e5a92e1
Merge branch 'master' into rpc-version-18
trim21 Jun 6, 2024
7ff6b1e
Merge branch 'master' into rpc-version-18
trim21 Jun 6, 2024
e80e2cf
Merge branch 'master' into rpc-version-18
trim21 Jun 9, 2024
7c1665c
Merge branch 'master' into rpc-version-18
trim21 Jun 9, 2024
1c30ba3
Merge branch 'master' into rpc-version-18
trim21 Jun 9, 2024
cfdd8e0
Merge branch 'master' into rpc-version-18
trim21 Jun 9, 2024
34554c7
Update README.md
trim21 Sep 20, 2024
1019a42
Merge branch 'master' into rpc-version-18
trim21 Sep 20, 2024
ffe59c3
Merge remote-tracking branch 'origin/master' into rpc-version-18
trim21 Dec 13, 2024
fc857fb
update readme
trim21 Dec 13, 2024
f8a5511
merge
trim21 Dec 13, 2024
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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
`transmission-rpc` is a python wrapper on top of [transmission](https://github.com/transmission/transmission) JSON RPC protocol,
hosted on GitHub at [github.com/trim21/transmission-rpc](https://github.com/trim21/transmission-rpc)

Support 2.40 (released 2011-10-05) <= transmission version <= 4.0.6 (released 2024-05-29),
Support 2.40 (released 2011-10-05) <= transmission version <= 4.1.0-beta.1 (released 2024-12-13),
should works fine with newer rpc version but some new feature may be missing.

## versioning
Expand Down
9 changes: 8 additions & 1 deletion docs/client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Client
Client is the class handling the Transmission JSON-RPC client protocol.

Torrent ids
------------
-----------

Many functions in Client takes torrent id.
You can find torrent-ids spec in `official docs
Expand All @@ -14,6 +14,8 @@ You can find torrent-ids spec in `official docs

It's recommended that you use torrent's ``info_hash`` as torrent id. The torrent's ``info_hash`` will never change.

Client
------

.. automodule:: transmission_rpc

Expand All @@ -22,6 +24,11 @@ You can find torrent-ids spec in `official docs
.. autoclass:: Client
:members:

.. autoclass:: PortTestResult
:members:
:undoc-members:
:inherited-members:
:exclude-members: __init__, __new__

Timeouts
--------
Expand Down
3 changes: 2 additions & 1 deletion transmission_rpc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
)
from transmission_rpc.session import Session, SessionStats, Stats
from transmission_rpc.torrent import FileStat, Status, Torrent, Tracker, TrackerStats
from transmission_rpc.types import File, Group
from transmission_rpc.types import File, Group, PortTestResult

__all__ = [
"DEFAULT_TIMEOUT",
Expand All @@ -21,6 +21,7 @@
"FileStat",
"Group",
"IdleMode",
"PortTestResult",
"Priority",
"RatioLimitMode",
"Session",
Expand Down
59 changes: 35 additions & 24 deletions transmission_rpc/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
)
from transmission_rpc.session import Session, SessionStats
from transmission_rpc.torrent import Torrent
from transmission_rpc.types import Group
from transmission_rpc.types import Group, PortTestResult
from transmission_rpc.utils import _try_read_torrent, get_torrent_arguments

try:
Expand Down Expand Up @@ -657,10 +657,11 @@
seed_idle_mode: int | None = None,
seed_ratio_limit: float | None = None,
seed_ratio_mode: int | None = None,
tracker_add: Iterable[str] | None = None,
labels: Iterable[str] | None = None,
group: str | None = None,
tracker_list: Iterable[Iterable[str]] | None = None,
sequential_download: bool | None = None,
tracker_add: Iterable[str] | None = None,
tracker_replace: Iterable[tuple[int, str]] | None = None,
tracker_remove: Iterable[int] | None = None,
**kwargs: Any,
Expand Down Expand Up @@ -692,35 +693,32 @@
Valid options are :py:class:`transmission_rpc.IdleMode`
labels: Array of string labels. Add in rpc 16.
group: The name of this torrent's bandwidth group. Add in rpc 17.
tracker_list:
A ``Iterable[Iterable[str]]``, each ``Iterable[str]`` for a tracker tier.

tracker_list: A ``Iterable[Iterable[str]]``, each ``Iterable[str]`` for a tracker tier.

Add in rpc 17.

Example: ``[['https://tracker1/announce', 'https://tracker2/announce'],
['https://backup1.example.com/announce'], ['https://backup2.example.com/announce']]``.

tracker_add:
Array of string with announce URLs to add.

Warnings:
since transmission daemon 4.0.0, this argument is deprecated, use ``tracker_list`` instead.

tracker_remove:
Array of ids of trackers to remove.
sequential_download: download torrent pieces sequentially. Add in Transmission 4.1.0, rpc-version 18.

Warnings:
since transmission daemon 4.0.0, this argument is deprecated, use ``tracker_list`` instead.
tracker_add: Array of string with announce URLs to add.
**Deprecated** since transmission daemon 4.0.0, this argument is deprecated,
use ``tracker_list`` instead.

tracker_replace:
Array of (id, url) tuples where the announcement URL should be replaced.
tracker_remove: Array of ids of trackers to remove.
**Deprecated** since transmission daemon 4.0.0, this argument is deprecated,
use ``tracker_list`` instead.

Warning:
since transmission daemon 4.0.0, this argument is deprecated, use ``tracker_list`` instead.
tracker_replace: Array of (id, url) tuples where the announcement URL should be replaced.
**Deprecated** since transmission daemon 4.0.0, this argument is deprecated,
use ``tracker_list`` instead.

Warnings:
``kwargs`` is for the future features not supported yet, it's not compatibility promising.
It will be bypassed to request arguments **as-is**, the underline in the key will not be replaced, so you should use kwargs like ``{'a-argument': 'value'}``
It will be bypassed to request arguments **as-is**,
the underline in the key will not be replaced, so you should use kwargs like ``{'a-argument': 'value'}``
"""
if labels is not None:
self._rpc_version_warning(16)
Expand Down Expand Up @@ -757,6 +755,7 @@
"labels": list_or_none(_single_str_as_list(labels)),
"trackerList": None if tracker_list is None else "\n\n".join("\n".join(tier) for tier in tracker_list),
"group": group,
"sequentialDownload": sequential_download,
}
)

Expand All @@ -779,7 +778,8 @@
Move torrent data to the new location.

See Also:
`RPC Spec: moving-a-torrent <https://github.com/transmission/transmission/blob/main/docs/rpc-spec.md#36-moving-a-torrent>`_
`RPC Spec: moving-a-torrent
<https://github.com/transmission/transmission/blob/main/docs/rpc-spec.md#36-moving-a-torrent>`_
"""
args = {"location": ensure_location_str(location), "move": bool(move)}
self._request(RpcMethod.TorrentSetLocation, args, ids, True, timeout=timeout)
Expand All @@ -799,7 +799,8 @@
This is not the method to move torrent data directory,

See Also:
`RPC Spec: renaming-a-torrents-path <https://github.com/transmission/transmission/blob/main/docs/rpc-spec.md#37-renaming-a-torrents-path>`_
`RPC Spec: renaming-a-torrents-path
<https://github.com/transmission/transmission/blob/main/docs/rpc-spec.md#37-renaming-a-torrents-path>`_
"""
self._rpc_version_warning(15)
torrent_id = _parse_torrent_id(torrent_id)
Expand Down Expand Up @@ -1094,13 +1095,23 @@
result = self._request(RpcMethod.BlocklistUpdate, timeout=timeout)
return result.get("blocklist-size")

def port_test(self, timeout: _Timeout | None = None) -> bool | None:
def port_test(
self, timeout: _Timeout | None = None, *, ip_protocol: Literal["ipv4", "ipv6"] | None = None
) -> PortTestResult:
"""
Tests to see if your incoming peer port is accessible from the
outside world.

https://github.com/transmission/transmission/blob/main/docs/rpc-spec.md#44-port-checking

Parameters:
ip_protocol: ``ipv4`` or ``ipv6``.
Available in Transmission 4.1.0 (rpc-version-semver 5.4.0, rpc-version: 18)
timeout: request timeout
"""
result = self._request(RpcMethod.PortTest, timeout=timeout)
return result.get("port-is-open")
return PortTestResult(

Check warning on line 1112 in transmission_rpc/client.py

View check run for this annotation

Codecov / codecov/patch

transmission_rpc/client.py#L1112

Added line #L1112 was not covered by tests
fields=self._request(RpcMethod.PortTest, remove_unset_value({"ipProtocol": ip_protocol}), timeout=timeout)
)

def free_space(self, path: str | pathlib.Path, timeout: _Timeout | None = None) -> int | None:
"""
Expand Down
1 change: 1 addition & 0 deletions transmission_rpc/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ class Type:
"seedIdleMode": Args(Type.number, 10, description="Use global (0), torrent (1), or unlimited (2) limit."),
"seedRatioLimit": Args(Type.double, 5, None, None, None, "Seed ratio limit."),
"seedRatioMode": Args(Type.number, 5, description="Use global (0), torrent (1), or unlimited (2) limit."),
"sequentialDownload": Args(Type.boolean, 18, description="download torrent pieces sequentially"),
"sizeWhenDone": Args(Type.number, 1, description="Size of the torrent download in bytes."),
"startDate": Args(Type.number, 1, description="The date when the torrent was last started."),
"status": Args(Type.number, 1, None, None, None, "Current status, see source"),
Expand Down
9 changes: 9 additions & 0 deletions transmission_rpc/torrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,15 @@
"""
return RatioLimitMode(self.fields["seedRatioMode"])

@property
def sequential_download(self) -> bool:
"""
download torrent pieces sequentially

add in Transmission 4.1.0 (rpc-version-semver 5.4.0, rpc-version: 18)
"""
return self.fields["sequentialDownload"]

Check warning on line 878 in transmission_rpc/torrent.py

View check run for this annotation

Codecov / codecov/patch

transmission_rpc/torrent.py#L878

Added line #L878 was not covered by tests

def __repr__(self) -> str:
return f"<transmission_rpc.Torrent hashString={self.hashString!r}>"

Expand Down
30 changes: 30 additions & 0 deletions transmission_rpc/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
class File(NamedTuple):
name: str
"""file name"""

size: int
"""file size in bytes"""

Expand All @@ -36,6 +37,12 @@
id: int
"""id of the file of this torrent, not should not be used outside the torrent scope"""

begin_piece: int | None = None
"""add in Transmission 4.1.0 rpc-version-semver 5.4.0, rpc-version 18"""

end_piece: int | None = None
"""add in Transmission 4.1.0 rpc-version-semver 5.4.0, rpc-version 18"""


class Group(Container):
"""
Expand Down Expand Up @@ -73,6 +80,29 @@
return self.fields["speed-limit-up"]


class PortTestResult(Container):
"""
api response of :meth:`transmission_rpc.Client.port_test`

https://github.com/transmission/transmission/blob/5d159e0/docs/rpc-spec.md#44-port-checking
"""

@property
def port_is_open(self) -> bool:
"""available on all transmission version"""
return self.fields["port-is-open"]

Check warning on line 93 in transmission_rpc/types.py

View check run for this annotation

Codecov / codecov/patch

transmission_rpc/types.py#L93

Added line #L93 was not covered by tests

@property
def ip_protocol(self) -> str:
"""``ipv4`` if the test was carried out on IPv4,
``ipv6`` if the test was carried out on IPv6,
unset if it cannot be determined

Available in Transmission 4.1.0 (rpc-version-semver 5.4.0, rpc-version: 18)
"""
return self.fields["ipProtocol"]

Check warning on line 103 in transmission_rpc/types.py

View check run for this annotation

Codecov / codecov/patch

transmission_rpc/types.py#L103

Added line #L103 was not covered by tests


class BitMap:
__value: bytes
__slots__ = ("__value",)
Expand Down