Navigation Menu

Skip to content

Commit

Permalink
support EventMachine (made Trnasmission::Client kinda ugly)
Browse files Browse the repository at this point in the history
  • Loading branch information
dsander committed Oct 27, 2009
1 parent a605666 commit 2eb064a
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 37 deletions.
29 changes: 25 additions & 4 deletions README.markdown
Expand Up @@ -6,7 +6,7 @@ The goal is to support all requests described in the Transmission [RPC Specifica
You need to have http://gemcutter.org in you gem sources. To add it you can execute either

sudo gem install gemcutter
sudo gem tumble`
sudo gem tumble

or

Expand All @@ -15,14 +15,35 @@ or
To install transmission-client:

sudo gem install transmission-client

If you want to use EventMachine (optional) you need to install the eventmachine gem and igrigorik's em-http-request:

sudo gem install eventmachine
sudo gem install em-http-request

## Usage
Get a list of torrents and print its file names:

require 'transmission-client'
t = Transmission::Client.new('192.168.0.2')
t = Transmission::Client.new('127.0.0.1', 9091)
t.torrents.each do |torrent|
puts torrent.name
puts torrent.name
end


To use the EventMachine driven interface:

require 'eventmachine'
require 'transmission-client'

EventMachine.run do
t = Transmission::Client.new
EM.add_periodic_timer(1) do
t.torrents do |torrents|
torrents.each do |tor|
puts tor.percentDone
end
end
end
end

RDoc is still to be written, at the meantime have a look at the code to find out which methods are supported.
31 changes: 26 additions & 5 deletions README.rdoc
@@ -1,12 +1,12 @@
# tranmission-client: A Transmission RPC Client
# transmission-client: A Transmission RPC Client

The goal is to support all requests described in the Transmission [RPC Specifications](http://trac.transmissionbt.com/browser/trunk/doc/rpc-spec.txt).

## Installing
You need to have http://gemcutter.org in you gem sources. To add it you can execute either

sudo gem install gemcutter
sudo gem tumble`
sudo gem tumble

or

Expand All @@ -15,14 +15,35 @@ or
To install transmission-client:

sudo gem install transmission-client

If you want to use EventMachine (optional) you need to install the eventmachine gem and igrigorik's em-http-request:

sudo gem install eventmachine
sudo gem install em-http-request

## Usage
Get a list of torrents and print its file names:

require 'transmission-client'
t = Transmission::Client.new('192.168.0.2')
t = Transmission::Client.new('127.0.0.1', 9091)
t.torrents.each do |torrent|
puts torrent.name
puts torrent.name
end


To use the EventMachine driven interface:

require 'eventmachine'
require 'transmission-client'

EventMachine.run do
t = Transmission::Client.new
EM.add_periodic_timer(1) do
t.torrents do |torrents|
torrents.each do |tor|
puts tor.percentDone
end
end
end
end

RDoc is still to be written, at the meantime have a look at the code to find out which methods are supported.
14 changes: 12 additions & 2 deletions lib/transmission-client.rb
@@ -1,11 +1,21 @@
require 'net/http'
require 'singleton'
require 'json'

require 'rubygems'
$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))

require 'transmission-client/client'
require 'transmission-client/connection'

if defined? EM
begin
require 'em-http'
require 'transmission-client/em-connection'
rescue LoadError
require 'transmission-client/connection'
end
else
require 'transmission-client/connection'
end
require 'transmission-client/torrent'
require 'transmission-client/session'

63 changes: 38 additions & 25 deletions lib/transmission-client/client.rb
Expand Up @@ -4,55 +4,68 @@ def initialize(host='localhost',port=9091)
Connection.instance.init(host, port)
end

def start_all
Connection.instance.send('torrent-start')
def start_all &cb
Connection.instance.send('torrent-start', &cb)
end

def start(id)
Connection.instance.send('torrent-start', {'ids' => id.class == Array ? id : [id]})
def start(id, &cb)
Connection.instance.send('torrent-start', {'ids' => id.class == Array ? id : [id]}, &cb)
end

def stop(id)
Connection.instance.send('torrent-stop', {'ids' => id.class == Array ? id : [id]})
def stop(id, &cb)
Connection.instance.send('torrent-stop', {'ids' => id.class == Array ? id : [id]}, &cb)
end

def stop_all
Connection.instance.send('torrent-stop')
def stop_all &cb
Connection.instance.send('torrent-stop', &cb)
end

def remove(id, delete_data = false)
Connection.instance.send('torrent-remove', {'ids' => id.class == Array ? id : [id], 'delete-local-data' => delete_data })
def remove(id, delete_data = false, &cb)
Connection.instance.send('torrent-remove', {'ids' => id.class == Array ? id : [id], 'delete-local-data' => delete_data }, &cb)
end

def remove_all(delete_data = false)
Connection.instance.send('torrent-remove', {'delete-local-data' => delete_data })
def remove_all(delete_data = false, &cb)
Connection.instance.send('torrent-remove', {'delete-local-data' => delete_data }, &cb)
end

def add_torrent(a)
def add_torrent(a, &cb)
if a['filename'].nil? && a['metainfo'].nil?
raise "You need to provide either a 'filename' or 'metainfo'."
end
Connection.instance.send('torrent-add', a)
Connection.instance.send('torrent-add', a, &cb)
end

def add_torrent_by_file(filename)
add_torrent({'filename' => filename})
def add_torrent_by_file(filename, &cb)
add_torrent({'filename' => filename}, &cb)
end

def add_torrent_by_data(data)
add_torrent({'metainfo' => data})
def add_torrent_by_data(data, &cb)
add_torrent({'metainfo' => data}, &cb)
end

def session
Session.new Connection.instance.request('session-get')
def session &cb
if cb
Connection.instance.request('session-get') { |resp| cb.call Session.new resp }
else
Session.new Connection.instance.request('session-get')
end
end

def torrents(fields = nil)
def torrents(fields = nil, &cb)
torrs = []
Connection.instance.request('torrent-get', {'fields' => fields ? fields : Transmission::Torrent::ATTRIBUTES})['torrents'].each do |t|
torrs << Torrent.new(t)
end
torrs
if cb
Connection.instance.request('torrent-get', {'fields' => fields ? fields : Transmission::Torrent::ATTRIBUTES}) { |resp|
resp['torrents'].each do |t|
torrs << Torrent.new(t)
end
cb.call torrs
}
else
Connection.instance.request('torrent-get', {'fields' => fields ? fields : Transmission::Torrent::ATTRIBUTES})['torrents'].each do |t|
torrs << Torrent.new(t)
end
torrs
end
end
end
end
51 changes: 51 additions & 0 deletions lib/transmission-client/em-connection.rb
@@ -0,0 +1,51 @@
module Transmission
class Connection
include Singleton
#include EM::Deferrable

def init(host, port)
@host = host
@port = port
uri = URI.parse("http://#{@host}:#{@port}/transmission/rpc")
#@conn = Net::HTTP.start(uri.host, uri.port)
@conn = EventMachine::HttpRequest.new(uri)
@header = {} #{"Accept-Encoding" => "deflate"} deflate is broken somewhere
end

def request(method, attributes={}, &cb)
req = @conn.post(:body => build_json(method,attributes), :head => @header )
req.callback {
if req.response_header.status == 409 #&& @header['x-transmission-session-id'].nil?
@header['x-transmission-session-id'] = req.response_header['X_TRANSMISSION_SESSION_ID']
request(method,attributes, &cb)
elsif req.response_header.status == 200
resp = JSON.parse(req.response)
if resp["result"] == 'success'
cb.call resp['arguments'] if cb
else
cb.call resp if cb
end
end
}
req.errback {
puts 'errback'
pp req
}
end

def send(method, attributes={}, &cb)
request(method, attributes) do |resp|
cb.call resp if cb
end
end

def build_json(method,attributes = {})
if attributes.length == 0
{'method' => method}.to_json
else
{'method' => method, 'arguments' => attributes }.to_json
end
end

end
end
1 change: 0 additions & 1 deletion lib/transmission-client/torrent.rb
Expand Up @@ -29,7 +29,6 @@ def remove(delete_data = false)
end

def method_missing(m, *args, &block)
pp m
if ATTRIBUTES.include? m.to_s
return @attributes[m.to_s]
elsif ADV_ATTRIBUTES.include? m.to_s
Expand Down

0 comments on commit 2eb064a

Please sign in to comment.