Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Torrent status change callbacks and authentication support

  • Loading branch information...
commit c7e144aee4883a994c83c0929b2ac87733e8ca09 1 parent 4807c9d
@dsander authored
View
39 README.markdown
@@ -1,6 +1,6 @@
# transmission-client: A Transmission RPC Client
-**Warning - The next release will drop support for the blocking api. Eventmachine will be required by then.**
+**Please note, with the current release i dropped support for the blocking api. Eventmachine is now required.**
The goal is to support all requests described in the Transmission [RPC Specifications](http://trac.transmissionbt.com/browser/trunk/doc/rpc-spec.txt).
@@ -18,24 +18,10 @@ 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('127.0.0.1', 9091)
- t.torrents.each do |torrent|
- puts torrent.name
- end
-
-To use the EventMachine driven interface:
-
- require 'eventmachine'
- require 'transmission-client'
EventMachine.run do
t = Transmission::Client.new
@@ -47,5 +33,28 @@ To use the EventMachine driven interface:
end
end
end
+
+Authentication support (thanks hornairs):
+
+ t = Transmission::Client.new('127.0.0.1', 9091, 'username', 'password')
+
+Callbacks:
+ EventMachine.run do
+ t = Transmission::Client.new
+
+ t.on_download_finished do |torrent|
+ puts "Wha torrent finished"
+ end
+ t.on_torrent_stopped do |torrent|
+ puts "Oooh torrent stopped"
+ end
+ t.on_torrent_started do |torrent|
+ puts "Torrent started."
+ end
+ t.on_torrent_removed do |torrent|
+ puts "Darn torrent deleted."
+ end
+ end
+
RDoc is still to be written, at the meantime have a look at the code to find out which methods are supported.
View
50 lib/transmission-client/client.rb
@@ -1,7 +1,14 @@
module Transmission
class Client
+ def on_download_finished(&blk); @on_download_finished = blk; callback_initialized; end
+ def on_torrent_added(&blk); @on_torrent_added = blk; callback_initialized; end
+ def on_torrent_stopped(&blk); @on_torrent_stopped = blk; callback_initialized; end
+ def on_torrent_started(&blk); @on_torrent_started = blk; callback_initialized; end
+ def on_torrent_removed(&blk); @on_torrent_removed = blk; callback_initialized; end
+
def initialize(host='localhost',port=9091, username = nil, password = nil)
Connection.init(host, port, username, password)
+ @torrents = nil
end
def start_all &cb
@@ -47,14 +54,53 @@ def session
Connection.request('session-get') { |resp| yield Session.new resp }
end
- def torrents(fields = nil)
- torrs = []
+ def torrents(fields = nil)
Connection.request('torrent-get', {'fields' => fields ? fields : Transmission::Torrent::ATTRIBUTES}) { |resp|
+ torrs = []
resp['torrents'].each do |t|
torrs << Torrent.new(t)
end
yield torrs
}
end
+
+ private
+ def callback_initialized
+ return if @torrent_poller
+ @torrent_poller = EM.add_periodic_timer(1) do
+ updated_torrents = {}
+ self.torrents do |tors|
+ tors.each do |torrent|
+ updated_torrents[torrent.id] = torrent
+ end
+ compare_torrent_status updated_torrents
+ @torrents = updated_torrents.dup
+ end
+
+
+ end
+ end
+
+ def compare_torrent_status updated_torrents
+ return false unless @torrents
+ updated_torrents.each_pair do |id, t|
+ old = @torrents[t.id] if @torrents[t.id]
+ if old == nil
+ @on_torrent_started.call t if @on_torrent_started
+ elsif old.downloading? && t.seeding?
+ @on_download_finished.call t if @on_download_finished
+ elsif old.stopped? && !t.stopped?
+ @on_torrent_started.call t if @on_torrent_started
+ elsif !old.stopped? && t.stopped?
+ @on_torrent_stopped.call t if @on_torrent_stopped
+ end
+ @torrents.delete t.id
+ end
+ if @torrents.length > 0 && @on_torrent_removed
+ @torrents.values.each do |t|
+ @on_torrent_removed.call t
+ end
+ end
+ end
end
end
View
37 lib/transmission-client/torrent.rb 100755 → 100644
@@ -3,31 +3,56 @@ class Torrent
ATTRIBUTES = ['activityDate', 'addedDate', 'bandwidthPriority', 'comment', 'corruptEver', 'creator', 'dateCreated', 'desiredAvailable', 'doneDate', 'downloadDir', 'downloadedEver', 'downloadLimit', 'downloadLimited', 'error', 'errorString', 'eta', 'hashString', 'haveUnchecked', 'haveValid', 'honorsSessionLimits', 'id', 'isPrivate', 'leftUntilDone', 'manualAnnounceTime', 'maxConnectedPeers', 'name', 'peer-limit', 'peersConnected', 'peersGettingFromUs', 'peersKnown', 'peersSendingToUs', 'percentDone', 'pieces', 'pieceCount', 'pieceSize', 'rateDownload', 'rateUpload', 'recheckProgress', 'seedRatioLimit', 'seedRatioMode', 'sizeWhenDone', 'startDate', 'status', 'swarmSpeed', 'totalSize', 'torrentFile', 'uploadedEver', 'uploadLimit', 'uploadLimited', 'uploadRatio', 'webseedsSendingToUs']
ADV_ATTRIBUTES = ['files', 'fileStats', 'peers', 'peersFrom', 'priorities', 'trackers', 'trackerStats', 'wanted', 'webseeds']
SETABLE_ATTRIBUTES = ['bandwidthPriority', 'downloadLimit', 'downloadLimited', 'files-wanted', 'files-unwanted', 'honorsSessionLimits', 'ids', 'location', 'peer-limit', 'priority-high', 'priority-low', 'priority-normal', 'seedRatioLimit', 'seedRatioMode', 'uploadLimit', 'uploadLimited']
+ CHECK_WAIT = 1
+ CHECK = 2
+ DOWNLOAD = 4
+ SEED = 8
+ STOPPED = 16
def initialize(attributes)
@attributes = attributes
end
def start
- Connection.instance.send('torrent-start', {'ids' => @attributes['id']})
+ Connection.send('torrent-start', {'ids' => @attributes['id']})
end
def stop
- Connection.instance.send('torrent-stop', {'ids' => @attributes['id']})
+ Connection.send('torrent-stop', {'ids' => @attributes['id']})
end
def verify
- Connection.instance.send('torrent-verify', {'ids' => @attributes['id']})
+ Connection.send('torrent-verify', {'ids' => @attributes['id']})
end
def reannounce
- Connection.instance.send('torrent-reannounce', {'ids' => @attributes['id']})
+ Connection.send('torrent-reannounce', {'ids' => @attributes['id']})
end
def remove(delete_data = false)
- Connection.instance.send('torrent-remove', {'ids' => @attributes['id'], 'delete-local-data' => delete_data })
+ Connection.send('torrent-remove', {'ids' => @attributes['id'], 'delete-local-data' => delete_data })
end
+ def downloading?
+ self.status == DOWNLOAD
+ end
+
+ def stopped?
+ self.status == STOPPED
+ end
+
+ def checking?
+ self.status == CHECK || self.status == CHECK_WAIT
+ end
+
+ def seeding?
+ self.status == SEED
+ end
+
+ def id
+ @attributes['id']
+ end
+
def method_missing(m, *args, &block)
if ATTRIBUTES.include? m.to_s
return @attributes[m.to_s]
@@ -35,7 +60,7 @@ def method_missing(m, *args, &block)
raise "Attribute not yet supported."
elsif m[-1..-1] == '='
if SETABLE_ATTRIBUTES.include? m[0..-2]
- Connection.instance.send('torrent-set', {'ids' => [@attributes['id']], m[0..-2] => args.first})
+ Connection.send('torrent-set', {'ids' => [@attributes['id']], m[0..-2] => args.first})
else
raise "Invalid Attribute."
end
Please sign in to comment.
Something went wrong with that request. Please try again.