2020-01-15 16:20:36 +01:00
|
|
|
import asyncio
|
|
|
|
import logging
|
|
|
|
import typing
|
|
|
|
|
|
|
|
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class TorrentInfo:
|
|
|
|
__slots__ = ('dht_seeds', 'http_seeds', 'trackers', 'total_size')
|
|
|
|
|
|
|
|
def __init__(self, dht_seeds: typing.Tuple[typing.Tuple[str, int]],
|
|
|
|
http_seeds: typing.Tuple[typing.Dict[str, typing.Any]],
|
|
|
|
trackers: typing.Tuple[typing.Tuple[str, int]], total_size: int):
|
|
|
|
self.dht_seeds = dht_seeds
|
|
|
|
self.http_seeds = http_seeds
|
|
|
|
self.trackers = trackers
|
|
|
|
self.total_size = total_size
|
|
|
|
|
|
|
|
@classmethod
|
2020-01-29 02:37:52 +01:00
|
|
|
def from_libtorrent_info(cls, torrent_info):
|
2020-01-15 16:20:36 +01:00
|
|
|
return cls(
|
2020-01-29 02:37:52 +01:00
|
|
|
torrent_info.nodes(), tuple(
|
2020-01-15 16:20:36 +01:00
|
|
|
{
|
|
|
|
'url': web_seed['url'],
|
|
|
|
'type': web_seed['type'],
|
|
|
|
'auth': web_seed['auth']
|
2020-01-29 02:37:52 +01:00
|
|
|
} for web_seed in torrent_info.web_seeds()
|
2020-01-15 16:20:36 +01:00
|
|
|
), tuple(
|
2020-01-29 02:37:52 +01:00
|
|
|
(tracker.url, tracker.tier) for tracker in torrent_info.trackers()
|
|
|
|
), torrent_info.total_size()
|
2020-01-15 16:20:36 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
class Torrent:
|
|
|
|
def __init__(self, loop, handle):
|
|
|
|
self._loop = loop
|
|
|
|
self._handle = handle
|
2021-08-21 05:33:21 +02:00
|
|
|
self.finished = asyncio.Event()
|
2020-01-15 16:20:36 +01:00
|
|
|
|
|
|
|
def _threaded_update_status(self):
|
|
|
|
status = self._handle.status()
|
|
|
|
if not status.is_seeding:
|
2020-01-29 02:37:52 +01:00
|
|
|
log.info(
|
|
|
|
'%.2f%% complete (down: %.1f kB/s up: %.1f kB/s peers: %d) %s',
|
2020-01-15 16:20:36 +01:00
|
|
|
status.progress * 100, status.download_rate / 1000, status.upload_rate / 1000,
|
2020-01-29 02:37:52 +01:00
|
|
|
status.num_peers, status.state
|
|
|
|
)
|
2020-01-15 16:20:36 +01:00
|
|
|
elif not self.finished.is_set():
|
|
|
|
self.finished.set()
|
|
|
|
|
|
|
|
async def wait_for_finished(self):
|
|
|
|
while True:
|
|
|
|
await self._loop.run_in_executor(
|
|
|
|
None, self._threaded_update_status
|
|
|
|
)
|
|
|
|
if self.finished.is_set():
|
|
|
|
log.info("finished downloading torrent!")
|
|
|
|
await self.pause()
|
|
|
|
break
|
2021-08-21 05:33:21 +02:00
|
|
|
await asyncio.sleep(1)
|
2020-01-15 16:20:36 +01:00
|
|
|
|
|
|
|
async def pause(self):
|
|
|
|
log.info("pause torrent")
|
|
|
|
await self._loop.run_in_executor(
|
|
|
|
None, self._handle.pause
|
|
|
|
)
|
|
|
|
|
|
|
|
async def resume(self):
|
|
|
|
await self._loop.run_in_executor(
|
|
|
|
None, self._handle.resume
|
|
|
|
)
|