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

Allow to change download location in rTorrent #49

Open
linost-xx opened this issue Oct 26, 2013 · 29 comments

Comments

Projects
None yet
@linost-xx
Copy link

commented Oct 26, 2013

As far as i know it is only possible to change download location if you use Transmission or Deluge. But i think it is possible to add this feature to rTorrent as well.

From what i understand from:

http://libtorrent.rakshasa.no/wiki/RTorrentXMLRPCGuide

Change the directory for a specific download.

xmlrpc localhost d.set_directory 91A2DF0C9288BC4C5D03EC8D8C26B4CF95A4DBEF foo/bar/

And:

http://libtorrent.rakshasa.no/wiki/RTorrentCommandsRaw

Index 55 String: 'd.directory'
Index 56 String: 'd.directory.set'
Index 57 String: 'd.directory_base'
Index 58 String: 'd.directory_base.set'

It should be doable.

@linost-xx

This comment has been minimized.

Copy link
Author

commented Dec 1, 2013

If someone is interested i have made some modifications to the code to support this feature. It's far from a perfect solution.

I modified the way "Set label" works so it instead sets a new download location.

It will by default download to your /default/download/locaton/ and if you "change label" it will download to /default/download/locaton/NewLabel

It also works to save to subdirs if you name the "label" Movies/Comedy/Disney for example.

Here is a screenshot: http://i40.tinypic.com/2mqrp1w.jpg

The location history list is based on labels from your other downloads.

Bugs

§1 If your download is in a folder - ex "/Suber Ubuntu Release/ubuntu.bin/" and you want to move the download to the folder "Linux" there will have to be an existing folder named "Linux" otherwise it wont work.

§2 When you change the download location the download will start from 0% so change it directly when you add it.

§3 When you change the location a copy of the original file will still be in /default/download/directory - I have made a cron job to emty that directory every hour.

So, if you want the code or apk send me a message.

@erickok

This comment has been minimized.

Copy link
Owner

commented Dec 2, 2013

It would be great to see that code. Do you have it in your own clone? (If you do, you haven't pushed it to GitHub yet.)

My guess is that you 'hijacked' the labels support because you didn't want to mess with the UI code. But there is already an option to change the download directory for torrents (with Transmission, for example). Any reason you dod not use that UI?

@linost-xx

This comment has been minimized.

Copy link
Author

commented Dec 2, 2013

No i had some trouble with importing from github so i just downloaded the .zip and imported from that.

Honestly i just wanted to use the label support because it looks awesome, and i have a autolabel feature on my server. So I actually never used it in transdroid.

Here is the code: > transdroid / lib / src / org / transdroid / daemon / Rtorrent / RtorrentAdapter.java

case SetLabel:
SetLabelTask labelTask = (SetLabelTask) task;
makeRtorrentCall("d.stop", new String[] { task.getTargetTorrent().getUniqueID() });
makeRtorrentCall("d.set_directory", new String[] { task.getTargetTorrent().getUniqueID(), task.getTargetTorrent().getLocationDir()+labelTask.getNewLabel() });
makeRtorrentCall("d.check_hash", new String[] { task.getTargetTorrent().getUniqueID() });
makeRtorrentCall("d.start", new String[] { task.getTargetTorrent().getUniqueID() });
return new DaemonTaskSuccessResult(task);

The problem is that, as far as i know xmlrpc don't support any "move" command. I don't know how you made it work in transmission but i suspect there is some php involved.

I'm considering if there is a way to use some kind of "event." to make rtorrent move the files but i havent found any solution for that yet.

@linost-xx

This comment has been minimized.

Copy link
Author

commented Dec 2, 2013

Or maybe an easier and more general solution would be to d.set_directory before starting the download in the first place. Like an "save as.." type of action.

@ncyclon

This comment has been minimized.

Copy link

commented Dec 4, 2013

Also wait for this feature. Sorry for offtop.

@erickok

This comment has been minimized.

Copy link
Owner

commented Mar 4, 2014

Already so it looks like I can just call d.set_directory, but it is far from ideal that any existing data is not moved. Is there another rTorrent command that can do that (too)? From http://libtorrent.rakshasa.no/wiki/RTorrentCommonTasks#Movecompletedtorrents I infer that you need a custom command.

If it is not possible, would you still like me to support this command?

@linost-xx

This comment has been minimized.

Copy link
Author

commented Mar 4, 2014

I have not been able to find a "move" command. But a custom command should work, I was looking at them but didn't really know what event to use for the command. But here is a list of events that can be used, don't know if there are any more.

  Index 159 String: 'event.download.closed'
  Index 160 String: 'event.download.erased'
  Index 161 String: 'event.download.finished'
  Index 162 String: 'event.download.hash_done'
  Index 163 String: 'event.download.hash_failed'
  Index 164 String: 'event.download.hash_final_failed'
  Index 165 String: 'event.download.hash_queued'
  Index 166 String: 'event.download.hash_removed'
  Index 167 String: 'event.download.inserted'
  Index 168 String: 'event.download.inserted_new'
  Index 169 String: 'event.download.inserted_session'
  Index 170 String: 'event.download.opened'
  Index 171 String: 'event.download.paused'
  Index 172 String: 'event.download.resumed'

But if it's not possible to get a "move" command to work it is as as you say not ideal. But in that case as i wrote above it might be better with a "save as" action where you set the default directory before starting the download. Then a move command wont be needed.

  Index 55 String: 'd.directory'
  Index 56 String: 'd.directory.set'
  Index 57 String: 'd.directory_base'
  Index 58 String: 'd.directory_base.set'

I'm guessing that d.directory_base.set would be the command to use in that case.

pseudo:

string baseDir = /standart/parth/ 

click to add torrent
set directory dialog
d.directory_base.set = /new/dir
d.start
d.directory_base.set = baseDir

and possibly an option in settings to enable/disable "save as"

@infernix

This comment has been minimized.

Copy link

commented Jul 17, 2014

I would like to ask that this is implemented as an optional dialog (server preference toggle) that shows itself whenever a torrent is sent to transdroid, preferably with a history of 3 or 5 dirs. This is how the Chrome Remote Torrent adder extension works.

As for moving data for already existing torrents, I believe rutorrent does the actual moving of data itself in php. It may be possible in rtorrent but I would view it as an additional feature.

The directory selection dialog alone would be a huge timesaver for me.

@infernix

This comment has been minimized.

Copy link

commented Aug 10, 2014

I've done some digging, and choosing the target download directory for rtorrent can completely be done through the XML API:

  • First use load_raw to load the torrent data in base64 encoding
  • Then get the state through d.state to ensure it's loaded (should return 0 for stopped)
  • Then change path with d.set_directory
  • Finally start with d.start

Relevant code from rt-cli:

(print "Adding torrent file '" tor "'" (if dest (string-append " to " dest) ""))
    (rt:cmd connection 'load_raw (string->blob (bencode torrent)))
      ;; check that torrent was added
      (if (rt:cmd connection 'd.state th)
          (begin
            (if dest (rt:cmd connection 'd.set_directory th dest))
            (rt:cmd connection 'd.start th))
          (begin
            (print "Hm. Seems torrent file wasn't added correctly. Aborting.")
            (exit 1))))

I tried looking for an existing interface to enter download directories but did not find it; is there one for other clients? Or is there just getDownloadDir()?

@alethenorio

This comment has been minimized.

Copy link

commented Jun 9, 2015

This is the one reason keeping me from using Transdroid with my rtorrent server other than looking at the status of my torrents sometimes.

Any chance this could be added to it?

@alexcoe

This comment has been minimized.

Copy link

commented Jun 12, 2015

If ruTorrent is added then php/addtorrent.php accepts a dir_edit parameter and httprpc already have works fine for the rpc calls

@guiled

This comment has been minimized.

Copy link

commented Dec 1, 2015

👍
I do need this feature. Thanks to all of you

@alethenorio

This comment has been minimized.

Copy link

commented Dec 3, 2015

Is there any progress update on this? Still being the only feature preventing me from using transdroid in a more meaningful way

@Eikichi60

This comment has been minimized.

Copy link

commented Dec 3, 2015

+1 please !

@pokegoo

This comment has been minimized.

Copy link

commented Aug 20, 2016

Yes would love this!

@vhodh

This comment has been minimized.

Copy link

commented Sep 20, 2016

Due to watch folders, subfolder auto labeling, and automove functions, being able to specify a download location is keeping me from using Transdroid.

rutorrent does indeed have an option to set a location and should be able to be hooked into.

Please implement this feature if possible! Thanks!!!

@alethenorio

This comment has been minimized.

Copy link

commented Sep 20, 2016

I think there is enough interest from people for this, the question is, is
it possible?

One thing to keep in mine is that ruTorrent does use SCGI while most
transdroid setups, though it seems to have support for it, probably do not.
Does transdroid support this if one use SCGI? Does rTorrent supports this
when not using no SCGI?

I think I tried once setting up ruTorrent on a separate machine from
rTorrent and found out it does not work so I am not sure how is transdroid
supposed to be able to work with it.

On Tue, 20 Sep 2016, 00:02 vhodh, notifications@github.com wrote:

Due to watch folders, subfolder auto labeling, and automove functions,
being able to specify a download location is keeping me from using
Transdroid.

rutorrent does indeed have an option to set a location and should be able
to be hooked into.

Please implement this feature if possible! Thanks!!!


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#49 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ACn1SynrzZfXCMpeE6U-tOcbn02nOvJ_ks5qr4T5gaJpZM4BI6sa
.

@erickok

This comment has been minimized.

Copy link
Owner

commented Sep 20, 2016

This is the thing. As far as I understand it, the way ruTorrent does it is by defining custom commands on rTorrent directly and using these custom commands afterwards via scgi. But Transdroid has no direct connection, so I have to rely on any existing commands. Now if we would know where (under what name) ruTorrent defines the command, Transdroid could call them as well. At least this way it will work for people who have set up ruTorrent too with their rTorrent setups.

@erickok

This comment has been minimized.

Copy link
Owner

commented Sep 20, 2016

To be clear, I know there exists a 'd.directory_base.set' command but that would not work for existing downloads as no data is moved. Hence, it is not what we are after.

@infernix

This comment has been minimized.

Copy link

commented Sep 20, 2016

@erickok but can't we at least add this functionality when adding a torrent? That would totally cover my use case at least?

As for moving, I dug into the source. ruTorrent does the moving itself within PHP. There isn't anything in rtorrent for moving data as far as I can see.

Some digging seems to point at ruTorrent calling this in plugins/datadir/action.php:

 $res = rtExec( "execute",
                        array( "sh",
                                "-c",
                                escapeshellarg($php)." ".escapeshellarg($script_dir."setdir.php").
                                        " ".$hash." ".escapeshellarg($datadir).
                                        " ".$move_addpath." ".$move_datafiles." ".$move_fastresume.
                                        " ".escapeshellarg(getUser())." & exit 0",
                        ),
                        $datadir_debug_enabled );

plugins/datadir/setdir.php then does:

# Script arguments are:
# 0: script name
# 1: hash
# 2: target datadir
# 3: flag, "1" means "add torrent's path"
# 4: flag, "1" means "move datafiles"
# 5: flag, "1" means "fast resume"
# 6: username

...

        if( !rtMkDir( $datadir, 0777 ) )
        {
                Debug( "can't create ".$datadir );
        }
        elseif( !rtSetDataDir( $hash, $datadir, 
                $move_addpath == '1', $move_datafiles == '1', $move_fastresume == '1',
                $datadir_debug_enabled ) )
        {
                Debug( "rtSetDataDir() fail!" );
        }

rtSetDataDir in plugins/datadir/util_setdir.php then calls back to rtorrent to get some variables:

     // Ask info from rTorrent
        if( $is_ok && $move_files )
        {
                $req = rtExec(
                        array(  "d.get_name", 
                                "d.get_base_path", 
                                "d.get_base_filename", 
                                "d.is_multi_file", 
                                "d.get_complete" ),
                        $hash, $dbg );

And a bit further down (after stopping and closing torrent):

if( !rtOpFiles( $torrent_files, $full_base_path, $full_dest_path, "Move", $dbg ) )
                                $is_ok = false;

rtOpFiles is in plugins/datadir/util_rt.php:

/------------------------------------------------------------------------------
// Make operation an array of files from $src directory to $dst directory
// ( files in array are relative to $src directory )
//------------------------------------------------------------------------------
function rtOpFiles( $files, $src, $dst, $op, $dbg = false )
{
...
                                if( !rtMoveFile( $source, $dest, $dbg ) )
                                        return false;
                                break;

And finally rtMoveFile in the same file:

//------------------------------------------------------------------------------
// Move $src file to $dst
//------------------------------------------------------------------------------
function rtMoveFile( $src, $dst, $dbg = false )
{
        $ss = LFS::stat($src);
        if( !rename( $src, $dst ) )
        {
                if( $dbg ) rtDbg( __FUNCTION__, "from ".$src );
                if( $dbg ) rtDbg( __FUNCTION__, "to   ".$dst );
                if( $dbg ) rtDbg( __FUNCTION__, "move fail, try to copy" );
                if( !copy( $src, $dst ) )
                {
                        if( $dbg ) rtDbg( __FUNCTION__, "copy fail" );
                        return false;
                }
                if( !unlink( $src ) )
                        if( $dbg ) rtDbg( __FUNCTION__, "delete fail (".$src.")" );
        }
        // there are problems here, if run-user is not file owner
        if($ss!==false)
                touch( $dst, $ss['mtime'], $ss['atime'] );
        return true;
}

The best way to mimic what ruTorrent itself does is to either post to plugins/datadir/action.php or to plugins/datadir/setdir.php

@erickok

This comment has been minimized.

Copy link
Owner

commented Sep 20, 2016

Right so ruTorrent has local script access, something which Transdroid cannot do. You are right that (IF the user has installed ruTorrent and IF those php scrips accept remote commands, something I doubt but have not checked) calling into those action/setdir.php scripts could be a solution, maybe.

@infernix

This comment has been minimized.

Copy link

commented Sep 20, 2016

@erickok and simply adding the option to specify a dir when adding a torrent is not acceptable?

@erickok

This comment has been minimized.

Copy link
Owner

commented Sep 20, 2016

That's a possibility but only 'simple' in the function sense. It would require a lot of work in the app. See #112 for my earlier concerns.

@infernix

This comment has been minimized.

Copy link

commented Sep 20, 2016

setdir.php looks for $argv so it can't be called.

But action.php can be called! Watch:

Using https://github.com/eliangcs/http-prompt:

https://my-server/rutorrent/plugins/datadir/action.php> post -f hash=FOOBARLONGTORRENTHASHSTRING datadir=/my/destination/path move_datafiles=1 move_addpath=1 move_fastresume=1

rutorrent output:

[20.09.16 15:57:43] 
[20.09.16 15:57:43] DataDir: --- begin ---
[20.09.16 15:57:43] DataDir: /my/destination/path
[20.09.16 15:57:43] DataDir: "add path", "move files", "fast resume"
[20.09.16 15:57:43] DataDir: script dir  : /var/www/rutorrent/plugins/datadir/
[20.09.16 15:57:43] DataDir: path to php : php
[20.09.16 15:57:43] DataDir: hash        : FOOBARLONGTORRENTHASHSTRING
[20.09.16 15:57:43] DataDir: data dir    : /my/destination/path
[20.09.16 15:57:43] DataDir: add path    : 1
[20.09.16 15:57:43] DataDir: move files  : 1
[20.09.16 15:57:43] DataDir: fast resume : 1
[20.09.16 15:57:43] rtExec: execute
[20.09.16 15:57:43] DataDir: --- end ---
[20.09.16 15:57:43] 
[20.09.16 15:57:43] SetDir: --- begin ---
[20.09.16 15:57:43] SetDir: hash        : FOOBARLONGTORRENTHASHSTRING
[20.09.16 15:57:43] SetDir: data dir    : /my/destination/path
[20.09.16 15:57:43] SetDir: add path    : 1
[20.09.16 15:57:43] SetDir: move files  : 1
[20.09.16 15:57:43] SetDir: fast resume : 1
[20.09.16 15:57:43] rtSetDataDir: hash        : FOOBARLONGTORRENTHASHSTRING
[20.09.16 15:57:43] rtSetDataDir: dest_path   : /my/destination/path
[20.09.16 15:57:43] rtSetDataDir: add path    : 1
[20.09.16 15:57:43] rtSetDataDir: move files  : 1
[20.09.16 15:57:43] rtSetDataDir: fast resume : 1
[20.09.16 15:57:43] rtExec: d.is_open, d.is_active
[20.09.16 15:57:43] rtSetDataDir: is_open=1, is_active=1
[20.09.16 15:57:43] rtExec: d.get_name, d.get_base_path, d.get_base_filename, d.is_multi_file, d.get_complete
[20.09.16 15:57:43] rtSetDataDir: d.get_name          : mytestfile.iso
[20.09.16 15:57:43] rtSetDataDir: d.get_base_path     : /the/current/path/mytestfolder/mytestfile.iso
[20.09.16 15:57:43] rtSetDataDir: d.get_base_filename : mytestfile.iso
[20.09.16 15:57:43] rtSetDataDir: d.is_multy_file     : 0
[20.09.16 15:57:43] rtSetDataDir: d.get_complete      : 1
[20.09.16 15:57:43] rtExec: f.multicall
[20.09.16 15:57:43] rtSetDataDir: files in torrent    : 1
[20.09.16 15:57:43] rtExec: d.stop, d.close
[20.09.16 15:57:43] rtSetDataDir: from /the/current/path/mytestfolder/
[20.09.16 15:57:43] rtSetDataDir: to  /my/destination/path/
[20.09.16 15:57:43] rtOpFiles: finished
[20.09.16 15:57:43] rtSetDataDir: clean /the/current/path/mytestfolder/
[20.09.16 15:57:43] rtSetDataDir: trying fast resume
[20.09.16 15:57:43] rtExec: get_session, d.get_tied_to_file, d.get_custom1, d.get_connection_seed, d.get_throttle_name
[20.09.16 15:57:43] rtExec: d.set_directory
[20.09.16 15:57:43] rtExec: d.erase
[20.09.16 15:57:43] rtSetDataDir: fast resume done
[20.09.16 15:57:43] rtSetDataDir: finished
[20.09.16 15:57:43] SetDir: --- end ---

So this is actually really simple. You just post the hash, the destination dir, and the optional flags.

move_addpath: "Don't add torrent's name to path"
move_datafiles: "Move data files"
move_fastresume: "Fast resume"

For all moves I've ever done, move_addpath=0 move_datafiles=1 move_fastresume=1 but YMMV between users.

@erickok, that's about as far as I can take it. Is calling action.php this way feasible?

@erickok

This comment has been minimized.

Copy link
Owner

commented Sep 20, 2016

Yes it is (given that the user has ruTorrent installed). Thanks for the work, I need to find some time now to work on it and try it myself.... 😊

@loubinator

This comment has been minimized.

Copy link

commented Feb 23, 2017

Hi guy, I'm really waiting for this feature, now you have the technical solution do you know where you'll have time to implement it?

Thanks a lot.

@infernix

This comment has been minimized.

Copy link

commented May 6, 2017

@erickok I know we're all busy all the time, but will you ever find time for this? Would sponsoring this work help with that? I've done the legwork and would submit a PR myself if it weren't for my lack of Java skills :)

@baragoon

This comment has been minimized.

Copy link

commented Dec 13, 2018

And one more year past :) any news?

@erickok

This comment has been minimized.

Copy link
Owner

commented Dec 14, 2018

I think you know the answer to that question.

Transdroid is in maintenance mode so don't expect anything feature-related at the moment any time soon, sorry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.