transmission-rpc-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,34 @@
1
+ module Transmission
2
+ class Arguments
3
+ class TorrentSet < Transmission::Arguments
4
+
5
+ ATTRIBUTES = [
6
+ 'bandwidthPriority',
7
+ 'downloadLimit',
8
+ 'downloadLimited',
9
+ 'downloadLimit',
10
+ 'files-wanted',
11
+ 'files-unwanted',
12
+ 'honorsSessionLimits',
13
+ 'ids',
14
+ 'location',
15
+ 'peer-limit',
16
+ 'priority-high',
17
+ 'priority-low',
18
+ 'priority-normal',
19
+ 'queuePosition',
20
+ 'seedIdleLimit',
21
+ 'seedIdleMode',
22
+ 'seedRatioLimit',
23
+ 'seedRatioMode',
24
+ 'trackerAdd',
25
+ 'trackerRemove',
26
+ 'trackerReplace',
27
+ 'uploadLimit',
28
+ 'uploadLimited',
29
+ 'uploadLimit'
30
+ ]
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ module Transmission
2
+ class Config
3
+ class << self
4
+ def set(options = {})
5
+ @@config = options
6
+ @@connector = Transmission::RPC.new @@config
7
+ end
8
+
9
+ def get
10
+ @@config
11
+ end
12
+
13
+ def get_connector
14
+ @@connector
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ require File.join(File.dirname(__FILE__), 'model', 'torrent')
2
+ require File.join(File.dirname(__FILE__), 'model', 'session')
3
+
4
+ module Transmission
5
+ module Model
6
+
7
+ end
8
+ end
@@ -0,0 +1,35 @@
1
+ module Transmission
2
+ module Model
3
+ class Session
4
+ class SessionError < StandardError; end
5
+
6
+ attr_accessor :attributes
7
+
8
+ def initialize(session_object)
9
+ @attributes = session_object
10
+ end
11
+
12
+ def version
13
+ @attributes['version'].split(' ').first
14
+ end
15
+
16
+ def rpc_version
17
+ @attributes['rpc-version']
18
+ end
19
+
20
+ class << self
21
+ def get(options = {})
22
+ rpc = options[:connector] || connector
23
+ session_body = rpc.get_session options
24
+ session_stats_body = rpc.get_session_stats options
25
+ merged_body = session_body.merge(session_stats_body)
26
+ Session.new merged_body
27
+ end
28
+
29
+ def connector
30
+ Transmission::Config.get_connector
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,97 @@
1
+ module Transmission
2
+ module Model
3
+ class Torrent
4
+ class TorrentError < StandardError; end
5
+ class TorrentNotFoundError < StandardError; end
6
+ class MissingAttributesError < StandardError; end
7
+ class DuplicateTorrentError < StandardError; end
8
+
9
+ attr_accessor :attributes, :deleted
10
+
11
+ def initialize(torrent_object)
12
+ @attributes = torrent_object
13
+ end
14
+
15
+ def delete!(remove_local_data = false)
16
+ Torrent.connector.remove_torrent [self.attributes['id']], remove_local_data
17
+ @deleted = true
18
+ end
19
+
20
+ def set
21
+
22
+ end
23
+
24
+ def move_up
25
+
26
+ end
27
+
28
+ def move_down
29
+
30
+ end
31
+
32
+ def move_top
33
+
34
+ end
35
+
36
+ def move_bottom
37
+
38
+ end
39
+
40
+ def start
41
+
42
+ end
43
+
44
+ def start_now
45
+
46
+ end
47
+
48
+ def stop
49
+
50
+ end
51
+
52
+ def verify
53
+
54
+ end
55
+
56
+ def re_announce
57
+
58
+ end
59
+
60
+ def finished?
61
+
62
+ end
63
+
64
+ def to_json
65
+
66
+ end
67
+
68
+ class << self
69
+ def all(options = {})
70
+ rpc = options[:connector] || connector
71
+ body = rpc.get_torrent nil, options
72
+ body['torrents'].inject([]) do |torrents, torrent|
73
+ torrents << Torrent.new(torrent)
74
+ end
75
+ end
76
+
77
+ def find(id, options = {})
78
+ rpc = options[:connector] || connector
79
+ body = rpc.get_torrent [id], options
80
+ raise TorrentNotFoundError if body['torrents'].size == 0
81
+ Torrent.new body['torrents'].first
82
+ end
83
+
84
+ def add(options = {})
85
+ rpc = options[:connector] || connector
86
+ body = rpc.add_torrent options[:arguments]
87
+ raise DuplicateTorrentError if body['torrent-duplicate']
88
+ find body['torrent-added']['id']
89
+ end
90
+
91
+ def connector
92
+ Transmission::Config.get_connector
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,108 @@
1
+ require File.join(File.dirname(__FILE__), 'rpc', 'connector')
2
+
3
+ module Transmission
4
+ class RPC
5
+
6
+ attr_accessor :session, :connector
7
+
8
+ def initialize(options = {})
9
+ @connector = Connector.new options
10
+ end
11
+
12
+ def get_session(options = {})
13
+ fields = Transmission::Arguments::SessionGet.new(options[:fields])
14
+ arguments = {fields: fields.to_arguments}
15
+ @connector.post method: 'session-get', arguments: arguments
16
+ end
17
+
18
+ def set_session(arguments)
19
+ @connector.post method: 'session-set', arguments: arguments
20
+ end
21
+
22
+ def get_session_stats(options = {})
23
+ fields = Transmission::Arguments::SessionStats.new(options[:fields])
24
+ arguments = {fields: fields.to_arguments}
25
+ @connector.post method: 'session-stats', arguments: arguments
26
+ end
27
+
28
+ def close_session
29
+ @connector.post method: 'session-close'
30
+ end
31
+
32
+ def test_port
33
+ @connector.post method: 'port-test'
34
+ end
35
+
36
+ def blocklist
37
+ @connector.post method: 'blocklist-update'
38
+ end
39
+
40
+ def get_torrent(ids = nil, options = {})
41
+ fields = Transmission::Arguments::TorrentGet.new(options[:fields])
42
+ arguments = {fields: fields.to_arguments}
43
+ arguments[:ids] = ids if ids.is_a?(Array)
44
+ @connector.post method: 'torrent-get', arguments: arguments
45
+ end
46
+
47
+ def set_torrent
48
+ @connector.post method: 'torrent-set'
49
+ end
50
+
51
+ def add_torrent(arguments = {})
52
+ @connector.post method: 'torrent-add', arguments: arguments
53
+ end
54
+
55
+ def remove_torrent(ids, delete_local_data = false)
56
+ @connector.post method: 'torrent-remove', arguments: {ids: ids, 'delete-local-data' => delete_local_data}
57
+ end
58
+
59
+ def free_space
60
+ @connector.post method: 'free-space'
61
+ end
62
+
63
+ def start_torrent
64
+
65
+ end
66
+
67
+ def start_torrent_now
68
+
69
+ end
70
+
71
+ def stop_torrent
72
+
73
+ end
74
+
75
+ def verify_torrent
76
+
77
+ end
78
+
79
+ def re_announce
80
+
81
+ end
82
+
83
+ def set_torrent_location
84
+
85
+ end
86
+
87
+ def rename_torrent_path
88
+
89
+ end
90
+
91
+ def move_up_torrent
92
+
93
+ end
94
+
95
+ def move_down_torrent
96
+
97
+ end
98
+
99
+ def move_top_torrent
100
+
101
+ end
102
+
103
+ def move_bottom_torrent
104
+
105
+ end
106
+
107
+ end
108
+ end
@@ -0,0 +1,69 @@
1
+ require 'faraday'
2
+ require 'json'
3
+
4
+ module Transmission
5
+ class RPC
6
+ class Connector
7
+ class AuthError < StandardError; end
8
+ class ConnectionError < StandardError; end
9
+ class InvalidSessionError < StandardError; end
10
+
11
+ attr_accessor :host, :port, :ssl, :credentials, :path, :session_id, :response
12
+
13
+ def initialize(options = {})
14
+ @host = options[:host] || 'localhost'
15
+ @port = options[:port] || 9091
16
+ @ssl = !!options[:ssl]
17
+ @credentials = options[:credentials] || nil
18
+ @path = options[:path] || '/transmission/rpc'
19
+ @session_id = options[:session_id] || ''
20
+ end
21
+
22
+ def post(params = {})
23
+ response = connection.post do |req|
24
+ req.url @path
25
+ req.headers['X-Transmission-Session-Id'] = @session_id
26
+ req.headers['Content-Type'] = 'application/json'
27
+ req.body = JSON.generate(params)
28
+ end
29
+ handle_response response
30
+ end
31
+
32
+ private
33
+
34
+ def json_body(response)
35
+ JSON.parse response.body
36
+ rescue
37
+ {}
38
+ end
39
+
40
+ def handle_response(response)
41
+ @response = response
42
+ if response.status == 409
43
+ @session_id = response.headers['x-transmission-session-id']
44
+ raise InvalidSessionError
45
+ end
46
+ body = json_body response
47
+ raise AuthError if response.status == 401
48
+ raise ConnectionError, body['result'] unless response.status == 200 && body['result'] == 'success'
49
+ body['arguments']
50
+ end
51
+
52
+ def connection
53
+ @connection ||= begin
54
+ connection = Faraday.new(:url => "#{scheme}://#{@host}:#{@port}", :ssl => {:verify => false}) do |faraday|
55
+ faraday.request :url_encoded
56
+ faraday.response :logger
57
+ faraday.adapter Faraday.default_adapter
58
+ end
59
+ connection.basic_auth(@credentials[:username], @credentials[:password]) if @credentials
60
+ connection
61
+ end
62
+ end
63
+
64
+ def scheme
65
+ @ssl ? 'https' : 'http'
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,60 @@
1
+ module Stubs
2
+
3
+ def stub_rpc_request(options = {})
4
+ host = options[:host] || 'localhost'
5
+ port = options[:port] || 9091
6
+ path = options[:path] || '/transmission/rpc'
7
+ scheme = !!options[:ssl] ? 'https' : 'http'
8
+ stub_request(:post, "#{scheme}://#{host}:#{port}#{path}")
9
+ end
10
+
11
+ def stub_get_torrent(body, torrents)
12
+ stub_rpc_request
13
+ .with(body: torrent_get_body(body))
14
+ .to_return(successful_response({arguments: {torrents: torrents}}))
15
+ end
16
+
17
+ def torrent_get_body(arguments = {})
18
+ args = {fields: Transmission::Arguments::TorrentGet.new.to_arguments}.merge(arguments)
19
+ {method: 'torrent-get', arguments: args}.to_json
20
+ end
21
+
22
+ def torrent_add_body(arguments = {})
23
+ {method: 'torrent-add', arguments: arguments}.to_json
24
+ end
25
+
26
+ def torrent_remove_body(arguments = {})
27
+ {method: 'torrent-remove', arguments: arguments}.to_json
28
+ end
29
+
30
+ def session_get_body(arguments = {})
31
+ {method: 'session-get', arguments: arguments}.to_json
32
+ end
33
+
34
+ def session_set_body(arguments = {})
35
+ {method: 'session-set', arguments: arguments}.to_json
36
+ end
37
+
38
+ def session_stats_body(arguments = {})
39
+ {method: 'session-stats', arguments: arguments}.to_json
40
+ end
41
+
42
+ def successful_response(options = {})
43
+ body = {result: 'success', arguments: (options[:arguments] || {})}
44
+ {status: 200, body: body.to_json, headers: options[:headers] || {}}
45
+ end
46
+
47
+ def unsuccessful_response(options = {})
48
+ body = {result: (options[:result] || ''), arguments: (options[:arguments] || {})}
49
+ {status: 200, body: body.to_json, headers: options[:headers] || {}}
50
+ end
51
+
52
+ def unauthorized_response(options = {})
53
+ {status: 401, body: (options[:body] || {}).to_json, headers: options[:headers] || {}}
54
+ end
55
+
56
+ def conflict_response(options = {})
57
+ {status: 409, body: (options[:body] || {}).to_json, headers: options[:headers] || {}}
58
+ end
59
+
60
+ end
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'webmock/rspec'
3
+
4
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'transmission')
5
+ require File.join(File.dirname(__FILE__), 'helpers', 'stubs')
6
+
7
+ ENV['TESTING'] = 'true'
8
+
9
+ RSpec.configure do |config|
10
+
11
+ config.include Stubs
12
+
13
+ end