So… I’ve been using rtorrent as my main torrent client for a couple of years now. I have it running on my server and I’m usually adding torrents either by placing them in a watchdir or by adding them through a web interface (rutorrent, in case you’re wondering).
One of the things I’ve always wanted was to have rtorrent handle multiple categories. I wanted games I downloaded to go into a “games” directory, comics into a “comics” directory, and so on. I’ve been looking for solutions for a few years now, and all I’ve found online are people in the same boat. So today I decided to spend a few hours experimenting… And this is the result.
The Solution
UPDATE 2022-07-07: Added updated code for rTorrent 0.9.6 at the end of the post!
My way of doing this uses two lines of code in .rtorrent.rc:
# Add new method to get finished dir system.method.insert = d.get_finished_dir,simple,"cat=[folder]/finished/,$d.get_custom1="
# Bind event "torrent has finished" to action "move to new directory based on label" system.method.set_key = event.download.finished,move_complete,"d.set_directory=$d.get_finished_dir=;execute=mkdir,-p,$d.get_finished_dir=;execute=mv,-u,$d.get_base_path=,$d.get_finished_dir="
The first line, the system.method.insert thing, basically says that each torrent object should be able to return a string which is the concatenation of “[folder]/finished/” and the torrent’s label. So a torrent with the label “tvshows” will return “[folder]/finished/tvshows”. Change the first part to whatever you want your base “finished torrents” directory to be. I haven’t tried this with any directories containing spaces, but I’m guessing escaping would be the way to go.
The second line basically says that the torrent should set its internally defined directory to whatever get_finished_dir returns, then create the directory if it doesn’t already exist, and finally move the torrent to the same directory.
- Torrents without labels will be placed in the base dir.
- Torrents with labels corresponding to already existing folders will be moved to those folders.
- Torrents with labels corresponding to folders that don’t already exist will have the folder created for them, then they’ll be moved to that folder.
It’s a bit complex, but hopefully my explanation makes thing a bit clearer =)
TL;DR: Insert the lines in your .rtorrent.rc, replace [folder]/finished/ with your base directory for finished torrents.
Watch directories
I have set up several watch directories, each corresponding to a category or label.
# TV shows schedule = watch_directory_1,5,60,"load_start=[folder]/input/tvshows/*.torrent,d.set_custom1=tvshows" # Movies schedule = watch_directory_1,5,60,"load_start=[folder]/input/movies/*.torrent,d.set_custom1=movies" # Comics schedule = watch_directory_1,5,60,"load_start=[folder]/input/comics/*.torrent,d.set_custom1=comics" # Music schedule = watch_directory_1,5,60,"load_start=[folder]/input/music/*.torrent,d.set_custom1=music"
There are two important parts of each of these lines. The [folder]/input/x part is the directory to be watched. The last part, after set_custom1=, is the label torrents found in the directory will be assigned.
This means when I’m downloading a movie, say, then I put the torrent in the [folder]/input/movies folder. It’s automatically added to rtorrent, with the label “movies”. When finished, it’s placed in [folder]/finished/movies.
Next step for me will be to add some automatic fetching of subtitles for downloaded movies and tv shows, but I’m pretty happy with this setup…
Update #1 (old)
I recently upgraded to rTorrent 0.6.9. Slight change as shown below:
# Add new method to get finished dir method.insert = d.get_finished_dir,simple,"cat=[folder]/finished/,$d.get_custom1="
method.set_key = event.download.finished,move_complete,"d.set_directory=$d.get_finished_dir=;execute=mkdir,-p,$d.get_finished_dir=;execute=mv,-u,$d.get_base_path=,$d.get_finished_dir="
I haven’t tested this extensively, though. I might come back to revise this further.
Update #2 (2022-07-07): rTorrent 0.9.6
I’ve switched to Flood as my interface and upgraded rTorrent, which meant I had to change some stuff. I’ve ditched the Watch Directories
This is what I have in my current .rtorrent.rc:
# Add new method to get finished dir (called get_finished_dir) method.insert = d.get_finished_dir,simple,"cat=[folder]finished/,$d.custom1=" # Bind event "torrent has finished" to action "move to new directory based on label" method.set_key = event.download.finished,move_complete,"d.directory.set=$d.get_finished_dir=;execute=mkdir,-p,$d.get_finished_dir=;execute=mv,-u,$d.base_path=,$d.get_finished_dir="
The changes are marked in bold. Remember to change [folder] to the folder where you want your torrents to go! I just don’t want to inform the entire internet exactly where on my server I keep stuff =)
Here’s also a more detailed breakdown of what the second line does (mostky for my own sake, so I don’t forget):
- method.set_key = event.download.finished,move_complete | Modifies the event.download.finished event to also have a new “key” called “move_complete”. From what I understand, rTorrent executes all “keys” in an event whenever that event is fired. The event.download.finished event fires whenever a torrent has finished downloading. The stuff within the quotation marks is the new key’s commands. Each command is separated by a semicolon (;).
- d.directory.set=$d.get_finished_dir=; | d.directory.set sets the directory of the torrent in rTorrent’s own information. It does not move the torrent, just means rTorrent will look in that directory from now on. $d.get_finished_dir just runs the get_finished_dir method preciously inserted; constructing a path name by combining [folder]/finished/ with whatever label was applied ($d.custom1 contains the label).
- execute=mkdir,-p,$d.get_finished_dir=; | Gets the same path name and makes sure the directory actually exists. Mkdir is the standard *nix command for creating directories. -p means creating parent directories if needed and not complaining if directory already exists.
- execute=mv,-u,$d.base_path=,$d.get_finished_dir= | Uses the same “execute” functionality as above to run the standard *nix mv command to move the torrent’s files (whose location is stored in d.base_path) to, once again, the directory whose name was constructed by the get_finished_dir method.
What happened between versions was basically that some of rTorrent’s internal scripting commands changed: d.get_custom1 became just d.custom1, and d.set_directory became d.directory.set.
Thanks to commenter “rTorrenter” for the new commands, worked like a charm. For me, at least.
Sources
I borrowed the method.insert stuff from this recipe.
The custom1 and label stuff I found in several places, but this solution is basically what I based mine on. I can’t seem to find the page where I found the information that the rutorrent labels are the same as d.get_current1 though.
I know there are addons for rutorrent (like autotools) that do similar things, but I wanted a server-based solution.
Got a better solution? Let me know and I’ll update this post & give credit!
Hi. Thanks for this. If I wanted to midofy it to make all downloads with no label to go to “/Other”, how would I do that?
Thanks, this helped a lot!
One issue, tho, that I had to sort out…
you can only use “watch_directory_1” one time as each subsequent use overrides the previous one. So in your example, it should be
TV Shows line – schedule = watch_directory_1,5,60 etc
Movies line – schedule = watch_directory_2
Comics line – schedule = watch_directory_3
etc etc
Hello, I really, really enjoy your code. It does so much more for me than you will ever know. I do have a follow up question/request if you would be willing to help me out. How would the code read if I wanted the following to happen. When I assign the torrent a label, lets say for example ” Always seed TVHD” how could I get it to put into a directory automatically that would be setup like this, which basically is just one more folder then you have, downloads/finished/Always_Seed/TVHD the first director is of course the default location of where all my torrents go to. This is a another example of the same thing, lets say I want to label a torrent “Seed to 1 TVHD” and it download automatically to a folder located here downloads/finished/Seed_to_1/TVHD. Basically I am just adding in a extra folder that was spoken of in your script and wondering how to do this,
Sorry, I haven’t really been tinkering much with this code as of late. I’ve forgotten most of it, and anyways part of it stopped working and I just gave up on the whole thing. Sorry I can’t help you!
Hey, this works in Debian Jessie’s rtorrent (0.92/0.13.2) and latest ruTorrent. Thanks for the tip.
Thank you for this!
Where is this guys ? LET ME PAY HIM A BEER !!
Thank you for posting this
this is awesome, thank you!
Hi,
excelent hack !! 🙂
I use autotools which work fine with watch folders (populated by sickrage and couchpotatoe) but not at all using rutorrent web GUI manual labelling.
Is this solution compatible with autotools in order to manage manual and automatic labelling ?
I’am afraid not …
Thx
I have no idea, sorry… Haven’t used autotools myself.
Hello,
This method still works?
I added the two lines in .rtorrent.rc but did nothing.
Do I have to restart the server? is necessary to change something more?
Thank you,
It should work, provided rtorrent is restarted. I’m using it myself. It’s possible there’s some version of rTorrent it doesn’t work with; I haven’t upgraded in forever…
I rebooted the server and it was OK.
I still have a problem if using a label composed of 2 folders “xpto/xpto” it works but creates a folder “xpto%2Fxpto”
Can you help?
this is perfect. excellent piece and a nice introduction to the blog. glad I ground this.
Out of interest did you get this working on rTorrent 0.9.8?
It was working fine on 0.9.6 but since upgrading I have to remove this code otherwise rTorrent doesn’t start.
This is what worked for me for rutorrent 3.6
directory = /defaultdownloadfolder/
method.insert = d.finished_dir,simple,”cat=/pathtobecopiedto/,$d.custom1=”
method.set_key = event.download.finished,move_complete,”d.directory=$d.finished_dir=;execute=mkdir,-p,$d.finished_dir=;execute=mv,-u,$d.base_path=,$d.finished_dir=”
This is what worked for me with rTorrent 0.9.8:
method.insert = d.get_finished_dir,simple,"cat=/path/to/finished/,$d.custom1="
method.set_key = event.download.finished,move_complete,"d.directory.set=$d.get_finished_dir=;execute=mkdir,-p,$d.get_finished_dir=;execute=mv,-u,$d.base_path=,$d.get_finished_dir="
Hello – I’m having a lot of trouble getting something like this working. I have about a 1000 torrents in my rtorrent 0.9.6 installation (running on unraid). I would like to create a script that allows the save path to dynamically change based on the label assigned. I tried both of the below scripts for a test file that was already downloaded and seeding, but it doesn’t seem to change the save path when I change the label. Does anyone know what I can do to get this working?
# Add new method to get finished dir
method.insert = d.get_finished_dir,simple,”cat=/data/,$d.get_custom1=”
method.set_key = event.download.finished,move_complete,”d.set_directory=$d.get_finished_dir=;execute=mkdir,-p,$d.get_finished_dir=;execute=mv,-u,$d.get_base_path=,$d.get_finished_dir=”
# Add new method to get finished dir
method.insert = d.get_finished_dir,simple,”cat=/data/,$d.custom1=”
method.set_key = event.download.finished,move_complete,”d.directory.set=$d.get_finished_dir=;execute=mkdir,-p,$d.get_finished_dir=;execute=mv,-u,$d.base_path=,$d.get_finished_dir=”
I’m not sure rTorrent scripting actually has the capability of detecting label changes, which is what you’d need. My scripts just hook into the “torrent has finished downloading” event (event.download.finished), which means my stuff just executed when the torrent first finishes downloading.
From what I can read on https://rtorrent-docs.readthedocs.io/en/latest/cmd-ref.html#event-commands , I can’t find anything about label changes. Maybe some commands could be scheduled? Or one could cheat a little bit, hooking into the paused/resumed events. I’d love to help out more but I just don’t have the time I’m afraid. I tried breaking down how I counstructed by scripts in the new update I posted, maybe that breakdown together with the link above can get you started?
Any update on this?
I just added a new update! Basically I got things working again by using rTorrenter’s solution as posted above.
Is it possible to do so that different label moves the torrent files to different locations?
For instance,
I would like the torrents labeled ‘Music’ to be moved to the folder /ssd/Music
But I want torrents labeled with ‘Movies’ to be moved to /hdd/Movies
Tack på förhand!
That is pretty much what the config I describe should do? At least, that’s what it does for me! As long as I apply the tag/label before the torrent finishes.