libtorrent icon indicating copy to clipboard operation
libtorrent copied to clipboard

Provide a way to change save path and rename files w/o touching files on disk

Open glassez opened this issue 2 years ago • 16 comments

For some purposes, it would be very convenient to have a way to change torrent save path and rename files without touching files on disk. I.e.:

  1. Stop any I/O and flush/close all the files,
  2. Change save path and/or rename some files without affecting any files on disk,
  3. Reset current progress and continue with the new save path and mapped file names.

glassez avatar May 13 '23 11:05 glassez

In particular, it would allow qBittorrent to avoid re-adding a torrent when received metadata, which we currently have to do in order to adjust save path and file names based on metadata. Ref.: https://github.com/qbittorrent/qBittorrent/pull/18845#issuecomment-1543983656.

glassez avatar May 13 '23 12:05 glassez

  • Stop any I/O and flush/close all the files,
  • Change save path and/or rename some files without affecting any files on disk,
  • Reset current progress and continue with the new save path and mapped file names.

In fact, it looks feasible regarding steps 1. and 3. using existing functionality, i.e. it can be achieved using pause() and force_recheck(). But the step 2. seems to be impossible now.

glassez avatar May 13 '23 12:05 glassez

@arvidn Since it will definitely require breaking API/ABI changes, I would be very grateful if you would consider it as early as possible so that it has a chance to get into upcoming v2.1 branch.

glassez avatar May 13 '23 12:05 glassez

Is the behaviour you're looking for different from removing the torrent and re-adding it with a new save path?

I suppose resume data may need to be cleared to some extent, since we won't know if the files exist at the new path or not

arvidn avatar May 14 '23 12:05 arvidn

I see, the tracker announce happens twice

arvidn avatar May 14 '23 12:05 arvidn

I don't think this would need to be an ABI break. torrent::move_storage() takes a flags field (move_flags_t) which has space left in it.

when you say "reset current progress"; you mean essentially to check resume-data and possibly perform a full check of the files, if there turns out to be existing files in the new save directory. Right?

arvidn avatar May 14 '23 14:05 arvidn

when you say "reset current progress"; you mean essentially to check resume-data and possibly perform a full check of the files, if there turns out to be existing files in the new save directory. Right?

As I said in https://github.com/arvidn/libtorrent/issues/7412#issuecomment-1546644457 it is what force_recheck() does (unless I missed some details about its exact behavior).

glassez avatar May 14 '23 15:05 glassez

@arvidn Apparently, I could confuse you with my few comments. This is due to the fact that I was thinking about how it would be possible to solve my specific task using current function of libtorrent with as few changes as possible. If we consider only my task itself, then we can say that we need a way to update/supplement the resume data at the moment the metadata is received. At first glance, it would be enough for this if libtorrent provided the ability to set a callback function that is called when metadata is received and allows you to change resume data. But this has a significant drawback, because it will occupy the main libtorrent thread. So the best option would be:

  1. Just notify the application when metadata is received and pass the metadata to it, e.g. via alert, but not actually apply it,
  2. Allow the application to update the resume data through a torrent_handle::set_metadata() call.

...then metadata processing can be performed asynchronously.

glassez avatar May 14 '23 16:05 glassez

I think the main new feature, in that scenario and any other that I can think of, is that you need a new state where a torrent is "started" and has announced to trackers once, but it's still in a somewhat paused state. When it has downloaded the metadata but hasn't applied it yet, there are a lot of cases that needs to be considered while in that state.

arvidn avatar May 14 '23 19:05 arvidn

you need a new state where a torrent is "started" and has announced to trackers once, but it's still in a somewhat paused state.

I wouldn't invent any new states. From the client (i.e. application) perspective it may look exactly the same as before, i.e. a torrent that does not have metadata. We need to add the following:

  1. a new flag that will indicate that the received metadata should not be applied automatically,
  2. metadata_received_alert should contain the metadata itself,
  3. torrent_handle::set_metadata() should accept add_torrent_params (or just some separate parameters) so that you can update those subset of add_torrent_params that make sense only after receiving the metadata (e.g. save path and mapped file names).

glassez avatar May 15 '23 12:05 glassez

Otherwise it can be done if libtorrent provided a feature of "atomic" retarget/relayout the file storage, that just "forgets" current storage and progress and starts from the scratch using new save path and mapped file names (extended version of force_recheck).

glassez avatar May 15 '23 12:05 glassez

https://github.com/arvidn/libtorrent/issues/7412#issuecomment-1547799440 looks like a more flexible feature, since it has a more general/abstract purpose, so it could be also used in some other scenarios.

glassez avatar May 15 '23 12:05 glassez

pause after metadata received flag?

ilayanyatto72733 avatar May 17 '23 17:05 ilayanyatto72733

pause after metadata received flag?

How could it help me?

glassez avatar May 18 '23 06:05 glassez

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Sep 17 '23 01:09 stale[bot]