transmission-rpc-ruby 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/.travis.yml +3 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +34 -3
- data/README.md +141 -47
- data/Rakefile +2 -0
- data/lib/transmission.rb +3 -1
- data/lib/transmission/arguments.rb +29 -6
- data/lib/transmission/arguments/session_set.rb +48 -48
- data/lib/transmission/arguments/torrent_add.rb +16 -12
- data/lib/transmission/arguments/torrent_set.rb +24 -24
- data/lib/transmission/fields.rb +42 -0
- data/lib/transmission/fields/session_get.rb +63 -0
- data/lib/transmission/fields/session_stats.rb +17 -0
- data/lib/transmission/fields/torrent_get.rb +78 -0
- data/lib/transmission/model/session.rb +19 -10
- data/lib/transmission/model/session_stats.rb +25 -0
- data/lib/transmission/model/torrent.rb +42 -27
- data/lib/transmission/rpc.rb +48 -44
- data/lib/transmission/rpc/connector.rb +3 -4
- data/lib/transmission/utils.rb +28 -0
- data/spec/helpers/stubs.rb +15 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/transmission/arguments_spec.rb +54 -7
- data/spec/transmission/fields_spec.rb +63 -0
- data/spec/transmission/model/session_spec.rb +84 -0
- data/spec/transmission/model/torrent_spec.rb +82 -0
- data/spec/transmission/rpc/connector_spec.rb +4 -3
- data/spec/transmission/rpc_spec.rb +3 -8
- data/spec/transmission/utils_spec.rb +70 -0
- data/transmission-rpc-ruby.gemspec +2 -2
- metadata +13 -6
- data/lib/transmission/arguments/session_get.rb +0 -63
- data/lib/transmission/arguments/session_stats.rb +0 -17
- data/lib/transmission/arguments/torrent_get.rb +0 -78
data/lib/transmission/rpc.rb
CHANGED
@@ -9,19 +9,15 @@ module Transmission
|
|
9
9
|
@connector = Connector.new options
|
10
10
|
end
|
11
11
|
|
12
|
-
def get_session(
|
13
|
-
fields = Transmission::
|
14
|
-
arguments = {fields: fields.
|
12
|
+
def get_session(fields = nil)
|
13
|
+
fields = Transmission::Fields::SessionGet.new(fields)
|
14
|
+
arguments = {fields: fields.to_fields}
|
15
15
|
@connector.post method: 'session-get', arguments: arguments
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
def get_session_stats(options = {})
|
23
|
-
fields = Transmission::Arguments::SessionStats.new(options[:fields])
|
24
|
-
arguments = {fields: fields.to_arguments}
|
18
|
+
def get_session_stats(fields = nil)
|
19
|
+
fields = Transmission::Fields::SessionStats.new(fields)
|
20
|
+
arguments = {fields: fields.to_fields}
|
25
21
|
@connector.post method: 'session-stats', arguments: arguments
|
26
22
|
end
|
27
23
|
|
@@ -37,71 +33,79 @@ module Transmission
|
|
37
33
|
@connector.post method: 'blocklist-update'
|
38
34
|
end
|
39
35
|
|
40
|
-
def
|
41
|
-
|
42
|
-
arguments = {fields: fields.to_arguments}
|
43
|
-
arguments[:ids] = ids if ids.is_a?(Array)
|
44
|
-
@connector.post method: 'torrent-get', arguments: arguments
|
36
|
+
def free_space
|
37
|
+
@connector.post method: 'free-space'
|
45
38
|
end
|
46
39
|
|
47
|
-
def
|
48
|
-
|
40
|
+
def get_torrent(ids, fields = nil)
|
41
|
+
fields = Transmission::Fields::TorrentGet.new(fields)
|
42
|
+
arguments = {fields: fields.to_fields}
|
43
|
+
arguments[:ids] = ids if ids.is_a? Array
|
44
|
+
@connector.post method: 'torrent-get', arguments: arguments
|
49
45
|
end
|
50
46
|
|
51
|
-
def
|
52
|
-
|
47
|
+
def set_torrent(ids, arguments)
|
48
|
+
arguments[:ids] = ids
|
49
|
+
arguments = Transmission::Arguments::TorrentSet.new(arguments)
|
50
|
+
@connector.post method: 'torrent-set', arguments: arguments.to_arguments
|
53
51
|
end
|
54
52
|
|
55
|
-
def
|
56
|
-
|
53
|
+
def set_session(arguments)
|
54
|
+
arguments = Transmission::Arguments::SessionSet.new(arguments)
|
55
|
+
@connector.post method: 'session-set', arguments: arguments.to_arguments
|
57
56
|
end
|
58
57
|
|
59
|
-
def
|
60
|
-
|
58
|
+
def add_torrent(arguments)
|
59
|
+
arguments = Transmission::Arguments::TorrentAdd.new(arguments)
|
60
|
+
@connector.post method: 'torrent-add', arguments: arguments.to_arguments
|
61
61
|
end
|
62
62
|
|
63
|
-
def
|
64
|
-
|
63
|
+
def remove_torrent(ids, delete_local_data = false)
|
64
|
+
@connector.post method: 'torrent-remove', arguments: {ids: ids, 'delete-local-data' => delete_local_data}
|
65
65
|
end
|
66
66
|
|
67
|
-
def
|
68
|
-
|
67
|
+
def start_torrent(ids)
|
68
|
+
@connector.post method: 'torrent-start', arguments: id_arguments(ids)
|
69
69
|
end
|
70
70
|
|
71
|
-
def
|
72
|
-
|
71
|
+
def start_torrent_now(ids)
|
72
|
+
@connector.post method: 'torrent-start-now', arguments: id_arguments(ids)
|
73
73
|
end
|
74
74
|
|
75
|
-
def
|
76
|
-
|
75
|
+
def stop_torrent(ids)
|
76
|
+
@connector.post method: 'torrent-stop', arguments: id_arguments(ids)
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
80
|
-
|
79
|
+
def verify_torrent(ids)
|
80
|
+
@connector.post method: 'torrent-verify', arguments: id_arguments(ids)
|
81
81
|
end
|
82
82
|
|
83
|
-
def
|
84
|
-
|
83
|
+
def re_announce_torrent(ids)
|
84
|
+
@connector.post method: 'torrent-reannounce', arguments: id_arguments(ids)
|
85
85
|
end
|
86
86
|
|
87
|
-
def
|
88
|
-
|
87
|
+
def move_up_torrent(ids)
|
88
|
+
@connector.post method: 'queue-move-up', arguments: id_arguments(ids)
|
89
89
|
end
|
90
90
|
|
91
|
-
def
|
92
|
-
|
91
|
+
def move_down_torrent(ids)
|
92
|
+
@connector.post method: 'queue-move-down', arguments: id_arguments(ids)
|
93
93
|
end
|
94
94
|
|
95
|
-
def
|
96
|
-
|
95
|
+
def move_top_torrent(ids)
|
96
|
+
@connector.post method: 'queue-move-top', arguments: id_arguments(ids)
|
97
97
|
end
|
98
98
|
|
99
|
-
def
|
100
|
-
|
99
|
+
def move_bottom_torrent(ids)
|
100
|
+
@connector.post method: 'queue-move-bottom', arguments: id_arguments(ids)
|
101
101
|
end
|
102
102
|
|
103
|
-
|
103
|
+
private
|
104
104
|
|
105
|
+
def id_arguments(ids)
|
106
|
+
arguments = {}
|
107
|
+
arguments[:ids] = ids if ids.is_a? Array
|
108
|
+
arguments
|
105
109
|
end
|
106
110
|
|
107
111
|
end
|
@@ -6,7 +6,6 @@ module Transmission
|
|
6
6
|
class Connector
|
7
7
|
class AuthError < StandardError; end
|
8
8
|
class ConnectionError < StandardError; end
|
9
|
-
class InvalidSessionError < StandardError; end
|
10
9
|
|
11
10
|
attr_accessor :host, :port, :ssl, :credentials, :path, :session_id, :response
|
12
11
|
|
@@ -26,7 +25,7 @@ module Transmission
|
|
26
25
|
req.headers['Content-Type'] = 'application/json'
|
27
26
|
req.body = JSON.generate(params)
|
28
27
|
end
|
29
|
-
handle_response response
|
28
|
+
handle_response response, params
|
30
29
|
end
|
31
30
|
|
32
31
|
private
|
@@ -37,11 +36,11 @@ module Transmission
|
|
37
36
|
{}
|
38
37
|
end
|
39
38
|
|
40
|
-
def handle_response(response)
|
39
|
+
def handle_response(response, params)
|
41
40
|
@response = response
|
42
41
|
if response.status == 409
|
43
42
|
@session_id = response.headers['x-transmission-session-id']
|
44
|
-
|
43
|
+
return self.post(params)
|
45
44
|
end
|
46
45
|
body = json_body response
|
47
46
|
raise AuthError if response.status == 401
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Transmission
|
2
|
+
module Utils
|
3
|
+
def is_valid_key?(key, attributes)
|
4
|
+
!attributes.select do |attribute|
|
5
|
+
option_keys(key).include? attribute[:field]
|
6
|
+
end.empty?
|
7
|
+
end
|
8
|
+
|
9
|
+
def option_keys(key)
|
10
|
+
split = key.to_s.split '_'
|
11
|
+
dashed = split.join '-'
|
12
|
+
camelcase = split.collect{|p| p.capitalize}.join
|
13
|
+
camelcase = camelcase[0].downcase + camelcase[1..-1]
|
14
|
+
[dashed, camelcase]
|
15
|
+
end
|
16
|
+
|
17
|
+
def option_key(key, attributes)
|
18
|
+
selected = attributes.select do |attribute|
|
19
|
+
option_keys(key).include? attribute[:field]
|
20
|
+
end
|
21
|
+
if selected.size > 0
|
22
|
+
selected.first[:field]
|
23
|
+
else
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/spec/helpers/stubs.rb
CHANGED
@@ -14,8 +14,14 @@ module Stubs
|
|
14
14
|
.to_return(successful_response({arguments: {torrents: torrents}}))
|
15
15
|
end
|
16
16
|
|
17
|
+
def stub_get_session(fields)
|
18
|
+
stub_rpc_request
|
19
|
+
.with(body: session_get_body({fields: fields}))
|
20
|
+
.to_return(successful_response)
|
21
|
+
end
|
22
|
+
|
17
23
|
def torrent_get_body(arguments = {})
|
18
|
-
args = {fields: Transmission::
|
24
|
+
args = {fields: Transmission::Fields::TorrentGet.new.to_fields}.merge(arguments)
|
19
25
|
{method: 'torrent-get', arguments: args}.to_json
|
20
26
|
end
|
21
27
|
|
@@ -27,6 +33,14 @@ module Stubs
|
|
27
33
|
{method: 'torrent-remove', arguments: arguments}.to_json
|
28
34
|
end
|
29
35
|
|
36
|
+
def torrent_set_body(arguments = {})
|
37
|
+
{method: 'torrent-set', arguments: arguments}.to_json
|
38
|
+
end
|
39
|
+
|
40
|
+
def torrent_method_body(method, arguments)
|
41
|
+
{method: method, arguments: arguments}.to_json
|
42
|
+
end
|
43
|
+
|
30
44
|
def session_get_body(arguments = {})
|
31
45
|
{method: 'session-get', arguments: arguments}.to_json
|
32
46
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,12 +1,9 @@
|
|
1
1
|
describe Transmission::Arguments do
|
2
2
|
|
3
3
|
[
|
4
|
-
{className: Transmission::Arguments::
|
5
|
-
{className: Transmission::Arguments::
|
6
|
-
{className: Transmission::Arguments::
|
7
|
-
{className: Transmission::Arguments::TorrentAdd, arguments: ['cookies']},
|
8
|
-
{className: Transmission::Arguments::TorrentGet, arguments: ['id']},
|
9
|
-
{className: Transmission::Arguments::TorrentSet, arguments: ['bandwidthPriority']}
|
4
|
+
{className: Transmission::Arguments::SessionSet, arguments: {'alt-speed-down' => 5}},
|
5
|
+
{className: Transmission::Arguments::TorrentAdd, arguments: {'paused' => true}},
|
6
|
+
{className: Transmission::Arguments::TorrentSet, arguments: {'location' => '/location'}}
|
10
7
|
].each do |klass|
|
11
8
|
|
12
9
|
describe "#{klass[:className]}" do
|
@@ -23,7 +20,7 @@ describe Transmission::Arguments do
|
|
23
20
|
|
24
21
|
it 'should raise an error if invalid arguments is given' do
|
25
22
|
expect {
|
26
|
-
klass[:className].new
|
23
|
+
klass[:className].new 'i-dont-exist' => ''
|
27
24
|
}.to raise_error(Transmission::Arguments::InvalidArgument)
|
28
25
|
end
|
29
26
|
end
|
@@ -31,4 +28,54 @@ describe Transmission::Arguments do
|
|
31
28
|
|
32
29
|
end
|
33
30
|
|
31
|
+
describe '.is_valid?' do
|
32
|
+
describe 'with valid key' do
|
33
|
+
it 'should return true' do
|
34
|
+
stub_const("Transmission::Arguments::ATTRIBUTES", [{field: 'test-me'}])
|
35
|
+
expect(Transmission::Arguments.is_valid?('test_me')).to eq(true)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'with invalid key' do
|
40
|
+
it 'should return true' do
|
41
|
+
stub_const("Transmission::Arguments::ATTRIBUTES", [{field: 'test-me'}])
|
42
|
+
expect(Transmission::Arguments.is_valid?('testMee')).to eq(false)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '.real_key' do
|
48
|
+
describe 'with valid key' do
|
49
|
+
it 'should return real key' do
|
50
|
+
stub_const("Transmission::Arguments::ATTRIBUTES", [{field: 'test-me'}])
|
51
|
+
expect(Transmission::Arguments.real_key('test_me')).to eq('test-me')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'with invalid key' do
|
56
|
+
it 'should return nil' do
|
57
|
+
stub_const("Transmission::Arguments::ATTRIBUTES", [{field: 'test-me'}])
|
58
|
+
expect(Transmission::Arguments.real_key('testMee')).to eq(nil)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '.filter' do
|
64
|
+
describe 'with valid keys' do
|
65
|
+
it 'should filter the correct keys' do
|
66
|
+
stub_const("Transmission::Arguments::ATTRIBUTES", [{field: 'test-me'}])
|
67
|
+
hash = {'test-me' => 'some-value'}
|
68
|
+
expect(Transmission::Arguments.filter(hash)).to eq(hash)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'with invalid keys' do
|
73
|
+
it 'should filter out the incorrect keys' do
|
74
|
+
stub_const("Transmission::Arguments::ATTRIBUTES", [{field: 'test-me'}])
|
75
|
+
hash = {'test-me' => 'some-value', 'incorrect-key' => 'some-value'}
|
76
|
+
expect(Transmission::Arguments.filter(hash)).to eq({'test-me' => 'some-value'})
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
34
81
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
describe Transmission::Fields do
|
2
|
+
|
3
|
+
[
|
4
|
+
{className: Transmission::Fields::SessionGet, fields: ['alt-speed-down']},
|
5
|
+
{className: Transmission::Fields::TorrentGet, fields: ['doneDate']},
|
6
|
+
{className: Transmission::Fields::SessionStats, fields: ['activeTorrentCount']}
|
7
|
+
].each do |klass|
|
8
|
+
|
9
|
+
describe "#{klass[:className]}" do
|
10
|
+
describe '#new' do
|
11
|
+
it 'should create an instance with correct fields' do
|
12
|
+
instance = klass[:className].new
|
13
|
+
expect(instance.fields.size).to eq(klass[:className]::ATTRIBUTES.size)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should create an instance with given fields' do
|
17
|
+
instance = klass[:className].new klass[:fields]
|
18
|
+
expect(instance.fields.size).to eq(1)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should raise an error if invalid arguments is given' do
|
22
|
+
expect {
|
23
|
+
klass[:className].new 'i-dont-exist' => ''
|
24
|
+
}.to raise_error(Transmission::Fields::InvalidField)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.is_valid?' do
|
32
|
+
describe 'with valid key' do
|
33
|
+
it 'should return true' do
|
34
|
+
stub_const("Transmission::Fields::ATTRIBUTES", [{field: 'test-me'}])
|
35
|
+
expect(Transmission::Fields.is_valid?('test_me')).to eq(true)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'with invalid key' do
|
40
|
+
it 'should return true' do
|
41
|
+
stub_const("Transmission::Fields::ATTRIBUTES", [{field: 'test-me'}])
|
42
|
+
expect(Transmission::Fields.is_valid?('testMee')).to eq(false)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '.real_key' do
|
48
|
+
describe 'with valid key' do
|
49
|
+
it 'should return real key' do
|
50
|
+
stub_const("Transmission::Fields::ATTRIBUTES", [{field: 'test-me'}])
|
51
|
+
expect(Transmission::Fields.real_key('test_me')).to eq('test-me')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'with invalid key' do
|
56
|
+
it 'should return nil' do
|
57
|
+
stub_const("Transmission::Fields::ATTRIBUTES", [{field: 'test-me'}])
|
58
|
+
expect(Transmission::Fields.real_key('testMee')).to eq(nil)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
describe Transmission::Model::Session do
|
2
|
+
|
3
|
+
describe '.get' do
|
4
|
+
|
5
|
+
describe 'with configuration' do
|
6
|
+
before :each do
|
7
|
+
Transmission::Config.set
|
8
|
+
stub_get_session(Transmission::Fields::SessionGet.new.to_fields)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should return a session model' do
|
12
|
+
session = Transmission::Model::Session.get
|
13
|
+
expect(session).to be_a(Transmission::Model::Session)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'with connector' do
|
18
|
+
before :each do
|
19
|
+
@rpc = Transmission::RPC.new
|
20
|
+
stub_get_session(Transmission::Fields::SessionGet.new.to_fields)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should return an array of Torrent models' do
|
24
|
+
session = Transmission::Model::Session.get connector: @rpc
|
25
|
+
expect(session).to be_a(Transmission::Model::Session)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#save!' do
|
31
|
+
let(:rpc) {Transmission::RPC.new}
|
32
|
+
|
33
|
+
before :each do
|
34
|
+
stub_const("Transmission::Arguments::SessionSet::ATTRIBUTES", [{field: 'name'}])
|
35
|
+
stub_get_session(Transmission::Fields::SessionGet.new.to_fields)
|
36
|
+
stub_rpc_request
|
37
|
+
.with(body: session_set_body({name: 'new value'}))
|
38
|
+
.to_return(successful_response)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should send the right parameters' do
|
42
|
+
session = Transmission::Model::Session.get connector: rpc
|
43
|
+
session.name = 'new value'
|
44
|
+
session.save!
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#method_missing' do
|
49
|
+
let(:session) { Transmission::Model::Session.new({'id' => 1, 'name' => 'some name', 'some-key' => 'some-value'}, nil) }
|
50
|
+
|
51
|
+
before :each do
|
52
|
+
stub_const("Transmission::Fields::SessionGet::ATTRIBUTES", [{field: 'id'}, {field: 'name'}, {field: 'some-key'}])
|
53
|
+
stub_const("Transmission::Arguments::SessionSet::ATTRIBUTES", [{field: 'name'}])
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'with existing attributes' do
|
57
|
+
it 'should return the correct values' do
|
58
|
+
expect(session.id).to eq(1)
|
59
|
+
expect(session.name).to eq('some name')
|
60
|
+
expect(session.some_key).to eq('some-value')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should set the correct values' do
|
64
|
+
session.name = 'ok'
|
65
|
+
expect(session.name).to eq('ok')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'with none existing attributes' do
|
70
|
+
it 'should raise error' do
|
71
|
+
expect {
|
72
|
+
session.i_dont_exist
|
73
|
+
}.to raise_error(NoMethodError)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should raise error' do
|
77
|
+
expect {
|
78
|
+
session.i_dont_exist = 'some value'
|
79
|
+
}.to raise_error(NoMethodError)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|