Skip to content

Commit

Permalink
fix(re-add): Remove unnecessary re-add sub-command
Browse files Browse the repository at this point in the history
/me slaps forehead

I don't remember how I concluded that:

> Unfortunately, Transmission provides no explicit way to apply it's logic for
> recognizing whether an item is completed and seeding without verifying is only run
> when adding a torrent and so re-adding is the only way to apply it for existing
> torrents.

But I just tested but simply starting a torrent works.
  • Loading branch information
rpatterson committed Nov 30, 2024
1 parent 0b35e23 commit 198526c
Show file tree
Hide file tree
Showing 36 changed files with 2 additions and 1,268 deletions.
3 changes: 2 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ services:
# Preserve shell history inside containers, requires `$ touch
# ./home/.bash_history`:
- "./home/.bash_history:/home/prunerr/.bash_history"
# Access to Transmission's data for the `$ prunerr re-add` sub-command:
# Access to Transmission's data to modify read-only `/config/resume/*.resume`
# properties:
- "./transmission/config/:/config/"
restart: "unless-stopped"

Expand Down
5 changes: 0 additions & 5 deletions newsfragments/+re-add-subcommand.feature.rst

This file was deleted.

19 changes: 0 additions & 19 deletions src/prunerr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,25 +162,6 @@ def export( # pylint: disable=missing-function-docstring,missing-return-doc
parser_export.set_defaults(command=export)


def re_add( # pylint: disable=missing-function-docstring,missing-return-doc
runner,
*args,
**kwargs,
) -> dict:
runner.update()
return runner.re_add(*args, **kwargs)


re_add.__doc__ = strip_api_docstring(prunerr.runner.PrunerrRunner.re_add.__doc__)
parser_re_add = subparsers.add_parser(
"re-add",
help=str(re_add.__doc__).strip(),
description=str(re_add.__doc__).strip(),
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser_re_add.set_defaults(command=re_add)


# Register shell tab completion
argcomplete.autocomplete(parser)

Expand Down
28 changes: 0 additions & 28 deletions src/prunerr/downloadclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,34 +240,6 @@ def clear(self):
for attr in ("config", "client"):
vars(self).pop(attr, None)

# Sub-commands

def re_add(self) -> list:
"""
Remove and re-add all download items with nothing downloaded.
:return: List all the items that were re-added to the download client.
"""
# Transmission seems to verify items in the order of their indexes, in the order
# they were added, so reverse the order to avoid clashing with items in the
# process of verifying:
re_add_results = []
for item in reversed(self.items):
# Skip items from the older full-list response first for speed:
if not item.re_add_check(self.seeding_dir):
continue # pragma: no cover
# Also get the latest item data in case it has finished verifying while
# previous items were re-added:
item.update()
if not item.re_add_check(self.seeding_dir): # pragma: no cover
logger.debug(
"Not re-adding download item whose metadata changed: %r",
item,
)
continue
re_add_results.append(item.re_add().name)
return re_add_results

# Methods to list the download items in each life-cycle stage:

def filter_queued(self) -> list: # noqa: V105
Expand Down
59 changes: 0 additions & 59 deletions src/prunerr/downloaditem.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class PrunerrDownloadItem(
STATUS_DOWNLOADING = "downloading"
STATUS_SEEDING = "seeding"
STATUS_SEEDING_INT = 6
STATUS_CHECKING = "checking"

def __init__(self, download_client, torrent):
"""
Expand Down Expand Up @@ -673,61 +672,3 @@ def remove(self) -> list:
download_client.client.get_session()

return deleted_paths

def re_add(self) -> "PrunerrDownloadItem":
"""
Remove and re-add this download item with the same item files location.
:return: The new item that results from re-adding this item.
"""
logger.info(
"Re-adding download item to client: %r",
self,
)
with open(self.torrent_file, mode="r+b") as torrent_opened:
self.download_client.client.remove_torrent(ids=[self.hash_string])
re_added = type(self)(
self.download_client,
self.download_client.client.add_torrent(
torrent=torrent_opened,
# These are the only fields from the `add_torrent()` call signature
# in the docs I could see corresponding fields for in the
# representation of a torrent.
bandwidthPriority=self.bandwidth_priority,
download_dir=str(self.download_dir),
peer_limit=self.peer_limit,
),
)
self.download_client.items.append(re_added)
# Some fields seem not to be populated in the object returned from
# `client.add_torrent()`:
re_added.update()
return re_added

def re_add_check(self, seeding_dir: pathlib.Path) -> bool:
"""
Decide and log whether to re-add this download item.
:param seeding_dir: Download items whose download directory is a descendant of
this directory should be re-added.
:return: True if this item should be added, False otherwise.
"""
if self.status == self.STATUS_CHECKING: # pragma: no cover
logger.debug(
"Not re-adding download item being verified: %r",
self,
)
return False
if seeding_dir not in self.path.parents: # pragma: no cover
logger.debug(
"Not re-adding download item not in the seeding directory: %r",
self,
)
return False
if self.progress: # pragma: no cover
logger.debug(
"Not re-adding download item with download progress: %r",
self,
)
return False
return True
25 changes: 0 additions & 25 deletions src/prunerr/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,31 +286,6 @@ def export(self) -> typing.Optional[dict]:
return export_results
return None

def re_add(self) -> typing.Optional[dict]:
"""
Remove and re-add all download items with nothing downloaded.
This is useful to avoid re-verifying seeding items when Transmission loses track
of the items progress such as when it's ``/config/resume/*.resume`` files are
lost or recreated. Unfortunately, Transmission provides no explicit way to
apply `it's logic for recognizing whether an item is completed and seeding
without verifying
<https://github.com/transmission/transmission/blob/9f77ef9c7ae32c1dcb7be79fca338f3ea1fb62fe/libtransmission/torrent.cc#L831>`_
is only run when adding a torrent and so re-adding is the only way to apply it
for existing torrents.
:return: Map each download client to the items that were re-added.
"""
re_add_results = {}

for download_client_url, download_client in self.download_clients.items():
if download_client_results := download_client.re_add(): # pragma: no cover
re_add_results[download_client_url] = download_client_results

if re_add_results:
return re_add_results
return None # pragma: no cover

def daemon(
self,
stages: collections.abc.Iterable = operations.STAGES_DEFAULT,
Expand Down
Loading

0 comments on commit 198526c

Please sign in to comment.