Skip to content

megantti/rtorrent-rpc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rtorrent-rpc

This library can be used for communicating with RTorrent over its JSON-RPC interface.

As an example, you can request torrent info and bandwidth usage:

result <- callRTorrent "tcp://localhost:5000" $ 
    getTorrents :*: getUpRate :*: getDownRate
case result of 
  Right (torrentInfo :*: uploadRate :*: downloadRate) -> ...

where

>>> :t torrentInfo
Vector TorrentInfo
>>> :t uploadRate
Int

This requires you to have set network.scgi.open_port = "127.0.0.1:5000" in your .rtorrent.rc, but this comes with security implications if your computer has multiple users.

Alternatively, you can setup RTorrent to open a UNIX socket with network.scgi.open_local , and then call

result <- callRTorrent "unix://~/.rtorrent/.session/socket.rpc" $ 
    ...

Note that :*: is both a data constructor and a type constructor, and therefore:

>>> :t True :*: False
Bool :*: Bool

However, using :*: in types needs the TypeOperators extension to work.

As a more complete example, the following code finds all files that are over 100 megabytes, prints them along with the torrent they belong to and sets their priorities to high.

{-# LANGUAGE TypeOperators #-}

import Control.Monad

import Data.Vector (Vector)
import qualified Data.Vector as V
import Data.Text (Text)
import qualified Data.Text as T

import Network.RTorrent

-- This is an action, and they can be combined with (<+>).
torrentInfo :: TorrentId
                -> TorrentAction (Text :*: Vector (FileId :*: Text :*: Int))
torrentInfo = getTorrentName 
               <+> allFiles (getFilePath <+> getFileSizeBytes)

    -- allFiles takes a file action (FileId -> FileAction a)
    -- and returns a torrent action: TorrentId -> TorrentAction [FileId :*: a].
    -- Note that it automatically adds FileIds to all elements.

main :: IO ()
main = do
    Right torrents <- callRTorrent "tcp://localhost:5000" $
                        allTorrents torrentInfo
    let largeFiles = 
                V.filter (\(_ :*: _ :*: _ :*: size) -> size > 10^8)
                . V.concatMap (\(tName :*: fileList) -> 
                                V.map ((:*:) tName) fileList) 
                             -- Move the torrent name into the list
                $ torrents

    putStrLn "Large files:"
    V.forM_ largeFiles $ \(torrent :*: _ :*: fPath :*: _) ->
        putStrLn $ "\t" ++ T.unpack torrent ++ ": " ++ T.unpack fPath

    -- There is instance ('Network.RTorrent.Command.Command' cmdA, 
    --                    'Network.RTorrent.Command.Command' cmdB) 
    --       => 'Network.RTorrent.Command.Command' (cmdA :*: cmdB)
    -- The return value for the command cmdA is 'Network.RTorrent.Command.Ret' cmdA,
    -- which is an associated type in the Command type class.
    -- The return value for the command cmdA :*: cmdB is Ret cmdA :*: Ret cmdB.
                     
    let cmd :: Text :*: FileId :*: Text :*: Int 
                -> FileAction FilePriority :*: FileAction Int
        cmd (_ :*: fid :*: _ :*: _) = 
            getFilePriority fid :*: setFilePriority FilePriorityHigh fid

            -- Get the old priority and set the new one to high.
            -- setFilePriority returns a not-so-useful Int.

    -- There is also an instance Command a => Command [a],
    -- and the return value for [a] is [Ret a].
    
    Right ret <- callRTorrent "tcp://localhost:5000" $ V.map cmd largeFiles

    putStrLn "Old priorities:"
    V.forM_ ret $ \(oldPriority :*: _) -> do
        putStrLn $ "\t" ++ show oldPriority

About

A Haskell library for interfacing with rtorrent using its XML-RPC interface.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors