Skip to content

Commit

Permalink
feat(torrent)!: return BitMap as .pieces instead of base64 str (#485
Browse files Browse the repository at this point in the history
)
  • Loading branch information
trim21 authored Dec 13, 2024
1 parent 952e4e8 commit a7c4047
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 10 deletions.
16 changes: 6 additions & 10 deletions transmission_rpc/torrent.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from __future__ import annotations

import base64
import enum
from datetime import datetime, timedelta, timezone
from functools import cached_property
from typing import Any

from typing_extensions import deprecated

from transmission_rpc.constants import IdleMode, Priority, RatioLimitMode
from transmission_rpc.types import Container, File
from transmission_rpc.types import BitMap, Container, File
from transmission_rpc.utils import format_timedelta

_STATUS_NEW_MAPPING = {
Expand Down Expand Up @@ -567,15 +569,9 @@ def percent_done(self) -> float:
"""
return float(self.fields["percentDone"])

@property
def pieces(self) -> str:
"""
A bitfield holding pieceCount flags which are set to 'true'
if we have the piece matching that position.
JSON doesn't allow raw binary data, so this is a base64-encoded string. (Source: tr_torrent)
"""
return self.fields["pieces"]
@cached_property
def pieces(self) -> BitMap:
return BitMap(base64.b64decode(self.fields["pieces"].encode()))

@property
def piece_count(self) -> int:
Expand Down
21 changes: 21 additions & 0 deletions transmission_rpc/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,24 @@ def speed_limit_up_enabled(self) -> bool:
def speed_limit_up(self) -> int:
"""max global upload speed (KBps)"""
return self.fields["speed-limit-up"]


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

def __init__(self, b: bytes):
self.__value = b

def get(self, index: int) -> bool:
"""
Args:
index: piece index
Returns:
this method always return a bool, even index overflow piece count of torrent.
This is because there is no reliable way to know piece count only based on `torrent.pieces`.
"""
try:
return bool(self.__value[index // 8] & (1 << (7 - (index % 8))))
except IndexError:
return False

0 comments on commit a7c4047

Please sign in to comment.